﻿using CameraMPSizector;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows;
using VisionConfig;

namespace FalionForm
{
    public  class Process
    {
        public MainWindow mw;
        public  MainPage mp;

        //曝光 灯光
        bool Lockd = false;

        int connectflg = 100;
       public  Process()
        {           
            double[] cameradata = { PublicData.infoIntiza.DilatedSize, PublicData.infoIntiza.SobelValue };
            checkDir(savePath);
            checkDir(onePath);
            connectflg=MPSizector.InitialCamera(cameradata);

            MainWindow.SClient.OnmessageEvent += RecMsg;
        }


        string savePath = "allImgPath/";
        string onePath = "Pictures/";
        public HObject ho_X = new HObject(), ho_Y = new HObject(), ho_Z = new HObject(), ho_M = new HObject();
        public static MPSizectorCamera MPSizector = new MPSizectorCamera();
        public HalconWindowProcess Vis3D = new HalconWindowProcess();
        public static HWindow hWindowID;
        public static HWindow HWindowID;
        public static HWindowControl HDC;
        public static HTuple hv_ObjectModel3DID = new HTuple();//3d模型结果
        public static HTuple ObjectModel3D_up = new HTuple();//3d模型结果
        public static bool IsSaveImg; //保存图片标志位
        public static bool OnlyCold; //仅显示点云
        public static bool Disp2D; //显示2D
        public static bool OffLine; //离线模式
        int Show3DMode = 0;
        public Thread tdisplay;

        public bool AutoFlg = false;

        /// <summary>
        /// 2号
        /// 3号
        /// </summary>
        int Position = 0;//拍摄工位

        /// <summary>
        /// 1号
        /// 5号
        /// </summary>
        int CarStyle = 0;//车型

        /// <summary>
        /// 0 正常
        /// 1 成像错误
        /// 2 无匹配结果
        /// 3 获取机器人坐标失败
        /// 4 相机断开
        /// 5 磨损
        /// </summary>
        int ErrorCode = 0;

        /// <summary>
        /// 1 存在定位销
        /// 2 圆孔
        /// </summary>
        int ResultFlg = 0;

        HTuple handeye = new HTuple();

        /// <summary>
        /// 清除点云
        /// </summary>
        /// <param name="Mod"></param>
        void ClearMod3D(HTuple Mod)
        {
            if (Mod.Type== HTupleType.HANDLE)
            {
                if (Mod.H.IsInitialized())
                {
                    HOperatorSet.ClearObjectModel3d(Mod);
                }          
            }
        }



        public int[] rp=new int[2];//两次结果
        public int RunTime = 0;
        //最终结果
        HTuple FinPose = new HTuple();


        string R_pick = "";
        string R_put = "";
        public bool IsRun = false;
       
        public void Raction(object k)
        {
            
            //3d模型
            HTuple ObjM3D_UP = new HTuple();
            HTuple ObjM3D_Main = new HTuple();
            HObject TX, TY, TZ, TG;/////////////////////////变量///////////////////////////////
            HOperatorSet.GenEmptyObj(out TX);
            HOperatorSet.GenEmptyObj(out TY);
            HOperatorSet.GenEmptyObj(out TZ);
            HOperatorSet.GenEmptyObj(out TG);
            int Positions = (int)k;

            IsRun = true;

            HTuple RBPose;


            HTuple outdisp = new HTuple();
            HOperatorSet.CreatePose(0, 0, 0, 0, 0, 0, "Rp+T", "gba", "point", out FinPose);


            try
            {
                //获取机器人坐标失败
                bool GetRobotPoint=GetRobotPose(out RBPose);//获取机器人坐标


                bool GrtBl=GetPicture(out TX, out TY, out TZ, out TG, OffLine);//获取图片


                if (!GrtBl)
                {
                    ErrorCode = 4;
                    mw.Mess("相机拍照失败");
                    goto End;
                }
                Collection(TX, TY, TZ, TG,false);//图片保存


                if (OnlyCold&&!Disp2D)////仅显示图片
                {
                    OnlyplayCould(TX, TY, TZ);
                    IsRun = false;
                    return;
                }
                if (Disp2D&&!OnlyCold)//显示2D图片
                {
                    setImagePart(TG, HDC);
                    HOperatorSet.DispImage(TG, HWindowID);
                    IsRun = false;
                    return;
                }


                int TypeN = 0; //0 头  1 座
                if (CarStyle == 1 || CarStyle == 3)
                {

                    if (Positions==2)
                    {
                        TypeN = 1;
                    }
                    else
                    {
                        TypeN = 0;
                    }
                }
                else
                {
                    if (Positions == 2)
                    {
                        TypeN = 0;
                    }
                    else
                    {
                        TypeN = 1;
                    }
                }




                //分割上半部分  //分割销头  与底座区分 提高稳定性
                //////////////////////////////////////////////////////////////////////////////////////////////
                HObject regions, reimg, hregion;
                HTuple area, rr, cc;
                HOperatorSet.Threshold(TZ, out regions, PublicData.infoIntiza.FillupMinArea, 150);

                //结合2d信息
                HOperatorSet.FastThreshold(TG, out hregion, 249, 255, 100);
                HOperatorSet.OpeningCircle(hregion, out hregion, 65);
                HOperatorSet.FillUp(hregion, out hregion);            
                HOperatorSet.Complement(hregion, out hregion);
                HOperatorSet.ReduceDomain(TZ, hregion, out TZ);



  


                hregion.Dispose();

                HOperatorSet.AreaCenter(regions,out area,out cc,out rr);
                bool haisPoint = false;
                if (area>100000)
                {
                    HTuple meaina, tmpsd;
                    HOperatorSet.Intensity(regions, TZ, out meaina, out tmpsd);
                    HOperatorSet.Threshold(TZ, out regions, PublicData.infoIntiza.FillupMinArea, meaina.D+25);
                   
                    
                    HOperatorSet.ReduceDomain(TZ, regions, out reimg);
                    regions.Dispose();

                    HTuple tmpmode;
                    HOperatorSet.XyzToObjectModel3d(TX, TY, reimg, out tmpmode);
                    HOperatorSet.SelectPointsObjectModel3d(tmpmode, new HTuple("num_neighbors_fast ") + 3, 400, 100000, out ObjM3D_UP);                 
                    try{HOperatorSet.ClearObjectModel3d(tmpmode);}catch { }
                    haisPoint = true;
                    reimg.Dispose();
                }
                else
                {
                    regions.Dispose();
                }



                //主区域
                HTuple tmp3d1=new HTuple();
                HOperatorSet.XyzToObjectModel3d(TX, TY, TZ, out tmp3d1);
                HOperatorSet.SelectPointsObjectModel3d(tmp3d1, new HTuple("num_neighbors_fast ") + 3, 400, 100000, out ObjM3D_Main);
                ClearMod3D(tmp3d1);





                HTuple haspoint;
                HOperatorSet.GetObjectModel3dParams(ObjM3D_Main, "has_points", out haspoint);
                if (haspoint=="false")
                {
                    //点云不存在 返回
                    ErrorCode = 1;
                    goto End;
                }

                //采样间距  百分比  最小得分  数量
                HTuple parameter=new HTuple(PublicData.infoIntiza.ErosionSize, PublicData.infoIntiza.FillupMaxArea, 
                    PublicData.infoIntiza.AreaMax, PublicData.infoIntiza.AreaMin);


                HTuple[] OutMat3d=new HTuple[0];
                HTuple OutScore=new HTuple();

                int ModelNum = 0;//模板选择 区分手动 自动/  从1开始
                if (AutoFlg)
                {
                    if (Positions == 2)
                    {
                        if (TypeN == 0)//检测头
                        {
                            if (haisPoint)
                            {
                                Match.Model3D_Match(ObjM3D_UP, UseData.Model3D[1], parameter, out OutMat3d, out OutScore);
                                if (OutMat3d.Length > 0)
                                {
                                    rp[0] = 3;
                                    ModelNum = 1;
                                }
                            }
                            if (!haisPoint || OutMat3d.Length == 0)
                            {
                                ModelNum = Positions;//位置号转换模板号
                                Match.Model3D_Match(ObjM3D_Main, UseData.Model3D[Positions], parameter, out OutMat3d, out OutScore);
                                if (OutMat3d.Length > 0)
                                {
                                    rp[0] = 1;//低位移动到高位
                                }
                                else
                                {
                                    rp[0] = 5; //待定
                                }
                            }

                        }
                        else//检测座子
                        {
                            ModelNum = Positions;//位置号转换模板号
                            Match.Model3D_Match(ObjM3D_Main, UseData.Model3D[Positions], parameter, out OutMat3d, out OutScore);
                            if (OutMat3d.Length == 0)
                            {
                                ModelNum = 1;
                                if (haisPoint)
                                {
                                    Match.Model3D_Match(ObjM3D_UP, UseData.Model3D[1], parameter, out OutMat3d, out OutScore);
                                }
                                if (haisPoint&&OutMat3d.Length > 0)
                                {
                                    rp[0] = 2;//高位移动到低位
                                }
                                else
                                {
                                    rp[0] = 5;
                                }
                            }
                            else
                            {
                                rp[0] = 3;
                            }
                        }
                   
                    }
                    else
                    {
                        if (TypeN == 0)//检测头
                        {
                            if (haisPoint)
                            {
                                Match.Model3D_Match(ObjM3D_UP, UseData.Model3D[1], parameter, out OutMat3d, out OutScore);
                                if (OutMat3d.Length > 0)
                                {
                                    rp[1] = 3;
                                    ModelNum = 1;
                                }
                            }
                            if (!haisPoint || OutMat3d.Length == 0)
                            {
                                ModelNum = Positions;//位置号转换模板号
                                Match.Model3D_Match(ObjM3D_Main, UseData.Model3D[Positions], parameter, out OutMat3d, out OutScore);
                                if (OutMat3d.Length > 0)
                                {
                                    rp[1] = 2;//高位移动到低位
                                }
                                else
                                {
                                    rp[1] = 5; //待定
                                }
                            }

                        }
                        else//检测座子
                        {
                            ModelNum = Positions;//位置号转换模板号
                            Match.Model3D_Match(ObjM3D_Main, UseData.Model3D[Positions], parameter, out OutMat3d, out OutScore);
                            if (OutMat3d.Length == 0)
                            {
                                ModelNum = 1;
                                if (haisPoint)
                                {
                                    Match.Model3D_Match(ObjM3D_UP, UseData.Model3D[1], parameter, out OutMat3d, out OutScore);
                                }
                                if (haisPoint && OutMat3d.Length > 0)
                                {
                                    rp[1] = 1;//低位移动到高位
                                }
                                else
                                {
                                    rp[1] = 5;
                                }
                            }
                            else
                            {
                                rp[1] = 3;
                            }
                        }

                    }
                }
                else
                {
                    ModelNum = PublicData.infoIntiza.Valid_range;
                    if (ModelNum == 1)
                    {
                        Match.Model3D_Match(ObjM3D_UP, UseData.Model3D[ModelNum], parameter, out OutMat3d, out OutScore);
                    } else if (ModelNum >= 2)
                    {
                        Match.Model3D_Match(ObjM3D_Main, UseData.Model3D[ModelNum], parameter, out OutMat3d, out OutScore);
                    }
                    
                }
                //清除
                if (haisPoint)//存在点云时 清空
                {
                    ClearMod3D(ObjM3D_UP);
                }


                //显示点云  序号从1开始
                Match.DispModel_Trans(UseData.Model3DDisp[ModelNum], OutMat3d, out outdisp);



                
                //有识别结果
                if (OutMat3d.Length>0&& OutScore[0].D>= PublicData.infoIntiza.AreaMax)
                {
                    #region    得到结果     
                    //提取准备姿态
                    HTuple PickPose;
                    HTuple UpPickPose;
                    HTuple UpUpPickPose;
                    HTuple TemPose;


                    //位置偏移从零开始
                    MatPick = OutMat3d[0];//保存识别结果
                    bool safeflg=GetWaitPose(OutMat3d[0], ModelNum-1, out PickPose, out UpPickPose, out UpUpPickPose, out TemPose);//disp

                    if (!safeflg)//超过安全位报错
                    {
                        ErrorCode = 5;
                    }

                    //获取机器人坐标
                    
                    HTuple RBPoseMat;//机器人坐标
                    RBPoseMat = new HTuple();
                    try
                    {                   
                        if (RBPose.Length==0)
                        {                          
                            mw.Mess("获取机器人坐标错误");
                            ErrorCode = 3;
                            FinPose = TemPose;
                            FinPose[6].D = OutScore[0].D;
                            goto End;
                        }
                        HOperatorSet.PoseToHomMat3d(RBPose, out RBPoseMat);
                        //读取标定
                        if (handeye.Length<3)
                        {
                            HOperatorSet.ReadTuple("handeye", out handeye);
                        }                   
                    }
                    catch
                    {
                        IsRun = false;
                        mw.Mess("读取标定文件失败");
                    }

                    //抓取姿态
                    HTuple quatPose, UpquatPose, UpUpquatPose, posetmp1, posetmp2, posetmp3;
                    TrnPose(handeye, RBPoseMat, PickPose, out quatPose,out posetmp1);
                    TrnPose(handeye, RBPoseMat, UpPickPose, out UpquatPose,out posetmp2);
                    TrnPose(handeye, RBPoseMat, UpUpPickPose, out UpUpquatPose, out posetmp3);
                    FinPose = posetmp1.Clone();

                    //转换字符串
                    string str1 = "";
                    string str2 = "";
                    string str3 = "";
                    if (AutoFlg)//自动模式下
                    {
                        for (int i = 0; i < quatPose.Length; i++)
                        {
                            str1 = str1 + quatPose[i].D.ToString("f4") + ",";
                            str2 = str2 + UpquatPose[i].D.ToString("f4") + ",";
                            str3 = str3 + UpUpquatPose[i].D.ToString("f4") + ",";
                        }
                        str1 = str1 + str2+ str3;
                        if (ModelNum == 1)
                        {
                            R_pick = str1;
                        }
                        else
                        {
                            R_put = str1;
                        }
                    }
                    else
                    {
                        if (safeflg)
                        {
                            for (int i = 0; i < quatPose.Length; i++)
                            {
                                str1 = str1 + quatPose[i].D.ToString("f4") + ",";
                                str2 = str2 + UpquatPose[i].D.ToString("f4") + ",";
                                str3 = str3 + UpUpquatPose[i].D.ToString("f4") + ",";
                            }
                        }
                        else
                        {
                            str1 = "0,0,0,0,0,0,0,";
                            str2 = "0,0,0,0,0,0,0,";
                            str3 = "0,0,0,0,0,0,0,";
                        }

                        str1 = str1 + str2 + str3;
                        if (ModelNum == 1)
                        {
                            str1 = str1 + "pick";
                        }
                        else
                        {
                            str1 = str1 + "put";
                        }
                        MainWindow.SClient.Send(str1);
                    }                 
                    FinPose[6].D= OutScore[0].D;
                    #endregion
                }




                End:
                //自动模式发送结果
                if (AutoFlg && Positions == 3)
                {
                    #region
                    int s = 4;
                    if (rp[0] == rp[1])
                    {
                        s = rp[0];
                        s = s == 5 ? 4 : s;
                    }
                    else
                    {
                        if (rp[0]==3&& rp[1]==5)
                        {
                            s = 3;
                        }
                        if (rp[0] == 5 && rp[1] == 3)
                        {
                            s = 3;
                        }
                    }


                    if (R_pick=="")
                    {
                        mw.Mess("位置码更新");
                        R_pick = "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,";
                    }
                    if (R_put == "")
                    {
                        mw.Mess("位置码更新");
                        R_put = "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,";
                    }
                    string ss = R_pick + R_put + s.ToString() +","+ ErrorCode.ToString();
                    RunTime = 0;
                    MainWindow.SClient.Send(ss);

                    #endregion
                }
          
                mp.DispInfomation(FinPose);//界面显示坐标结果

                ObjM3D_Main.Append(outdisp);//点云图 与匹配结果组合
                Show3DMode = 1;  //彩色显示


                if (!Lockd)
                {
                    Lockd = true;
                    StopDispImage();//停止上一次显示             
                    if (ObjM3D_Main.Type == HTupleType.HANDLE)
                    {
                        if (ObjM3D_Main.H.IsInitialized())
                        {
                            StartDispImage(ObjM3D_Main);
                        }
                    }
                    Lockd = false;
                }
                else
                {
                    ClearMod3D(ObjM3D_Main);
                }



                IsRun = false;
                TX.Dispose();
                TY.Dispose();
                TZ.Dispose();
                TG.Dispose();
                GC.Collect();
                return;

            }
            catch (HalconException HDevExpDefaultException)
            {
                ClearMod3D(ObjM3D_Main);
                ClearMod3D(ObjM3D_UP);
                TX.Dispose();
                TY.Dispose();
                TZ.Dispose();
                TG.Dispose();
                IsRun = false;
                return;
            }
        }

        void thtest()
        {
            try
            {
                //点云匹配
                HOperatorSet.ClearObjectModel3d(hv_ObjectModel3DID);
                HOperatorSet.ClearObjectModel3d(hv_ObjectModel3DID);
                HOperatorSet.ClearObjectModel3d(hv_ObjectModel3DID);
                HOperatorSet.ClearObjectModel3d(hv_ObjectModel3DID);
                HOperatorSet.ClearObjectModel3d(hv_ObjectModel3DID);
            }
            catch
            {

            }
        }


    bool  GetWaitPose(HTuple Mat3D,int Num,out HTuple PickPose,out HTuple UpPickPose, out HTuple UpUpPickPose, out HTuple TemPoses)//获取准备坐标
        {
            //提取准备姿态
            HTuple WaitPose, WaitM2d;
            HTuple UpPose, UpUpPose, UpM2d, UpUpM2d;
            HTuple TemPose;

            HOperatorSet.CreatePose(PublicData.Clist[Num].X, PublicData.Clist[Num].Y, PublicData.Clist[Num].Z
                , PublicData.Clist[Num].g, PublicData.Clist[Num].b, PublicData.Clist[Num].a
                , "Rp+T", "gba", "point", out WaitPose);

            UpPose = WaitPose.Clone();
            UpUpPose = WaitPose.Clone();
            UpPose[2].D += PublicData.infoIntiza.SobelMinTheshold;//提升距离
            UpUpPose[2].D += PublicData.infoIntiza.SobelMinTheshold+220;//提升距离

            HOperatorSet.PoseToHomMat3d(WaitPose, out WaitM2d);//等待姿态转换矩阵

            HOperatorSet.HomMat3dToPose(Mat3D, out TemPoses);//匹配结果姿态
            //TemPoses = TemPose.Clone();


           // mw.Mess("X:"+ TemPoses[3].D.ToString()+"Y:"+ TemPoses[4].D.ToString());
            bool flg = true;
            //////////
            double ax = TemPoses[3];
            double ay = TemPoses[4];
            if (TemPoses[3]>=270)
            {
                ax = 360 - TemPoses[3];
            }
            if (TemPoses[4] >= 270)
            {
                ay = 360 - TemPoses[4];
            }

            if (ax>=10||ay>10)
            {
                if ((ax>=173&&ax<=187&&ay<=10)|| (ay >= 173 && ay <= 187 && ax <= 10))
                {
                    HTuple hv_TempAngle = 180;
                    HOperatorSet.HomMat3dRotateLocal(Mat3D, hv_TempAngle.TupleRad(), "x", out Mat3D);
                    HOperatorSet.HomMat3dToPose(Mat3D, out TemPose);//匹配结果姿态
                    mw.Mess("销头角度安全纠正：");
                    goto fff;
                }
                mw.Mess("销头超出空间角度：");
                flg = false;
                TemPose = TemPoses;
            }
            else
            {
                TemPose = TemPoses;
            }
            fff:

            /////////


           
            switch (Num)///选择抓取方向
            {
                case 0:
                   // mw.Mess("销头角度 :"+(TemPose[5].D).ToString());  274  265.5   86.89
                    if (TemPose[5].D < 106&& TemPose[5].D>70)
                    {
                        TemPose[5].D = TemPose[5].D + 180;
                    }
                    //250 286
                    if (TemPose[5].D<250|| TemPose[5].D>286)
                    {
                        mw.Mess("销头超出抓取角度 ：" + (TemPose[5].D).ToString());
                        flg = false;
                    }
                    break;
                case 1:
                    //mw.Mess("高位销座角度 :" + (TemPose[5].D * 57.29578).ToString());  183 176.29 357
                    if (TemPose[5].D < 18 || TemPose[5].D > 338)
                    {
                        TemPose[5].D = TemPose[5].D + 180;
                    }
                    if (TemPose[5].D >= 360)
                    {
                        TemPose[5].D = TemPose[5].D - 360;
                    }
                    if (TemPose[5].D < 158 || TemPose[5].D > 198)//198  158
                    {
                        mw.Mess("高位销座超出放置角度 ：" + (TemPose[5].D).ToString());
                        flg = false;
                    }
                    break;
                case 2:
                   // mw.Mess("低位销座角度 :" + (TemPose[5].D * 57.29578).ToString()); 360
                    if (TemPose[5].D < 18 || TemPose[5].D > 342)
                    {
                        TemPose[5].D = TemPose[5].D + 180;
                    }
                    if (TemPose[5].D>=360)
                    {
                        TemPose[5].D = TemPose[5].D - 360;
                    }
                    if (TemPose[5].D < 162 || TemPose[5].D > 198)
                    {
                        mw.Mess("低位销座超出放置角度 ：" + (TemPose[5].D).ToString());
                        flg = false;
                    }
                    break;
                default:
                    break;
            }
            HOperatorSet.PoseToHomMat3d(TemPose, out Mat3D);
            HOperatorSet.HomMat3dCompose(Mat3D, WaitM2d, out PickPose);//获取实际抓取姿态

            


            HOperatorSet.PoseToHomMat3d(UpPose, out UpM2d);//等待姿态转换矩阵
            HOperatorSet.HomMat3dCompose(Mat3D, UpM2d, out UpPickPose);//获取实际抓取姿态
            HOperatorSet.PoseToHomMat3d(UpUpPose, out UpUpM2d);//等待姿态转换矩阵
            HOperatorSet.HomMat3dCompose(Mat3D, UpUpM2d, out UpUpPickPose);//获取实际抓取姿态

            return flg;
        }



        bool AngeAdgust(double InAng,double Set,double OffSet)//未完成
        {

            return true;

        }
        void TrnPose(HTuple handeye, HTuple RBPoseMat,HTuple PickPose,out HTuple quatPose, out HTuple UlarPose)//获取抓取坐标
        {
            if (handeye.Length > 6 && RBPoseMat.Length > 6)
            {
                HTuple InvPose;
                HOperatorSet.PoseInvert(handeye, out InvPose);//标定求逆
                HTuple HandeyeMat;
                HOperatorSet.PoseToHomMat3d(InvPose, out HandeyeMat);//标定转换矩阵
                MatH = HandeyeMat;//保存手眼
                MatRobot = RBPoseMat;//保存机器人


                HTuple FinPose;//抓取坐标欧拉角
                //抓取矩阵转换
                HTuple tmpd, PickMat;
                HOperatorSet.HomMat3dCompose(HandeyeMat, PickPose, out tmpd);
                HOperatorSet.HomMat3dCompose(RBPoseMat, tmpd, out PickMat);
                HOperatorSet.HomMat3dToPose(PickMat, out FinPose);

                UlarPose = FinPose.Clone();
                HTuple QuatPose;
                HOperatorSet.PoseToQuat(FinPose, out QuatPose);

                HTuple TmpStr = FinPose.TupleSelectRange(0, 2);
                TmpStr.Append(QuatPose);
                quatPose = TmpStr.Clone();
            }
            else
            {
                quatPose = new HTuple();
                UlarPose = new HTuple();
            }
        }

        //获取机器人坐标
        string msg;
        public bool GetRobotPose(out HTuple Pose)
        {
            //获取机器人坐标
            msg = "";
            MainWindow.SClient.Send("point");

            //接受数据
            int add = 0;
            while (true)
            {
                add++;
                Thread.Sleep(10);
                if (msg!="")
                {
                    break;
                }
                if (add>120)
                {
                    mw.Mess("机器人通信失败");
                    break;
                }
            }
            

            string[] data = msg.Split(',');
            Pose = new HTuple();

            if (data.Length != 7)
            {
                return false;
            }

            HTuple Quat = new HTuple(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
            double m;
            for (int i = 0; i < data.Length; i++)
            {
                m = Convert.ToDouble(data[i]);
                Quat[i].D = m;
            }

            HTuple Tmp = Quat.TupleSelectRange(0, 2);
            HTuple QuatA = Quat.TupleSelectRange(3, 6);
            HOperatorSet.QuatToPose(QuatA, out Pose);
            Pose[0].D = Tmp[0].D;
            Pose[1].D = Tmp[1].D;
            Pose[2].D = Tmp[2].D;
            return true;
        }
        void RecMsg(string str)
        {
            string[] StrList = str.Split(',');
            if (StrList.Length>6)
            {
                msg = str;
            }
            if (StrList.Length==3 && StrList[0]=="get"&& AutoFlg)
            {
                try
                {
                    Position = Convert.ToInt32(StrList[2])+1;
                    CarStyle = Convert.ToInt32(StrList[1]);

                    if (Position>3|| Position<2|| CarStyle<1|| CarStyle>6)
                    {
                        mw.Mess("位置码错误、车型不在工艺配方之内");
                        MessageBox.Show("位置码错误、车型不在工艺配方之内");
                        return;
                    }
                }
                catch 
                {
                    mw.Mess("位置码格式错误");
                    MessageBox.Show("位置码格式错误");
                    return;
                }
                if (IsRun&&false)
                {
                    mw.Mess("拍照命令错误、连续触发拍照");
                    return;
                    
                }

                if (AutoFlg && Position == 2)
                {
                    R_pick = "";
                    R_put = "";
                    rp[0] = -1;
                    rp[1] = -1;
                    ErrorCode = 0;
                }

                Th = new Thread(new ParameterizedThreadStart(Raction));
                Th.IsBackground = true;
                Th.Start(Position);
            }
        }
        Thread Th;



        //标定算法
        public void Calib(out HTuple DisModel,out HTuple Pose)
        {
            GetPicture(out ho_X, out ho_Y, out ho_Z, out ho_M, OffLine);//获取图片
            Collection(ho_X, ho_Y, ho_Z, ho_M,false);//图片保存

            //点云匹配          
            try
            {
                HOperatorSet.ClearObjectModel3d(hv_ObjectModel3DID);
            }
            catch { }
            HOperatorSet.XyzToObjectModel3d(ho_X, ho_Y, ho_Z, out hv_ObjectModel3DID);

            //采样间距  百分比  最小得分  数量
            HTuple parameter = new HTuple(PublicData.infoIntiza.ErosionSize, PublicData.infoIntiza.FillupMaxArea,
                PublicData.infoIntiza.AreaMax, PublicData.infoIntiza.AreaMin);


            HTuple[] OutMat3d;
            HTuple OutScore;
            Match.Model3D_Match(hv_ObjectModel3DID, UseData.Model3D[4], parameter, out OutMat3d, out OutScore);
            HTuple outdisp;
            HTuple pose = new HTuple();
            //存在匹配结果
            if (OutMat3d.Length == 1&& OutScore[0].D >0.4)
            {
                Match.DispModel_Trans(UseData.Model3DDisp[4], OutMat3d, out outdisp);
                HOperatorSet.HomMat3dToPose(OutMat3d[0], out pose);
                hv_ObjectModel3DID.Append(outdisp);
                Show3DMode = 1;
            }
            else
            {

            }
            Pose = pose.Clone();
            DisModel = hv_ObjectModel3DID;
        }
        //线程池
        public void Pretreatment()
        {
            List<ManualResetEvent> manualEvents = new List<ManualResetEvent>();

            for (int i = 0; i < 5; i++)
            {
                ManualResetEvent mre = new ManualResetEvent(false);
                manualEvents.Add(mre);
                Param pra = new Param();
                pra.mrEvent = mre;
                pra.praData = i;
                ThreadPool.QueueUserWorkItem(ThreadMethod, pra);
            }
            WaitHandle.WaitAll(manualEvents.ToArray());
        }
        public class Param
        {
            public ManualResetEvent mrEvent;
            public int praData;
        }
        private void ThreadMethod(object obj)
        {
            Thread.Sleep(2000);
            Param pra = (Param)obj;
            pra.mrEvent.Set();
            Console.WriteLine("Thread execute at {0}", pra.praData);
        }




        public void Arithmetic(HTuple Object3D,int ModelNum)
        {
            //参数输入
            //采样间距  百分比  最小得分  数量
            HTuple parameter = new HTuple(PublicData.infoIntiza.ErosionSize, PublicData.infoIntiza.FillupMaxArea,
                PublicData.infoIntiza.AreaMax, PublicData.infoIntiza.AreaMin);

            HTuple[] OutMat3d;
            HTuple OutScore;
            Match.Model3D_Match(hv_ObjectModel3DID, UseData.Model3D[ModelNum], parameter, out OutMat3d, out OutScore);
        }


        /// /////////////////////////////////////////////////////////////////////////////////////////////
   
        HTuple MatPick, MatH, MatRobot;
        public void CaliAngle()
        {
            HTuple RBPose, RBPoseMat;
            HTuple MatPick_1, MatH_1, MatRobot_1;
            HTuple tmp;
            GetRobotPose(out RBPose);//获取机器人坐标
            try
            {
                HTuple pose;
                HOperatorSet.HomMat3dInvert(MatPick,out MatPick_1);
                HOperatorSet.HomMat3dInvert(MatH, out MatH_1);
                HOperatorSet.HomMat3dInvert(MatRobot, out MatRobot_1);
                if (RBPose.Length >0)
                {
                    HOperatorSet.PoseToHomMat3d(RBPose, out RBPoseMat);
                    HOperatorSet.HomMat3dCompose(MatRobot_1, RBPoseMat, out tmp);
                    HOperatorSet.HomMat3dCompose(MatH_1, tmp, out tmp);
                    HOperatorSet.HomMat3dCompose(MatPick_1, tmp, out tmp);
                    HOperatorSet.HomMat3dToPose(tmp, out pose);

                    string str = "";
                    for (int i = 0; i < pose.Length; i++)
                    {
                        str = str + pose[i].D.ToString("f4") + ",";
                    }
                    MessageBox.Show(str);
                }                
            }
            catch { }
        }


        //获取图片
        private bool GetPicture(out HObject X, out HObject Y, out HObject Z, out HObject G, bool offline=false)
        {
            HOperatorSet.GenEmptyObj(out X);
            HOperatorSet.GenEmptyObj(out Y);
            HOperatorSet.GenEmptyObj(out Z);
            HOperatorSet.GenEmptyObj(out G);
            if (offline)
            {
                try
                {
                    //1.离线读取3个方向投影图像
                    HObject img3;
                    HOperatorSet.ReadImage(out img3, "./" + onePath + "/DColor");
                    HOperatorSet.Decompose3(img3, out X, out Y, out Z);
                    HOperatorSet.ReadImage(out G, "./" + onePath + "/ho_M");
                    return true;
                }
                catch
                {                  
                    return false;
                }
            }
            else
            {
                try
                {
                    MPSizector.GenPicture();
                    X = MPSizectorCamera.XPicture.Clone();
                    Y = MPSizectorCamera.YPicture.Clone();
                    Z = MPSizectorCamera.ZPicture.Clone();
                    G = MPSizectorCamera.GrayPicture.Clone();
                    return true;
                }
                catch 
                {

                    MessageBox.Show("相机连接失败");
                    return false;
                }
            }
        }
        string desktop="";
        int counts = 0;
        //图片保存
        private void Collection(HObject ho_X, HObject ho_Y, HObject ho_Z, HObject ho_M,bool focus)
        {
            if (!(ho_X != null && ho_X.IsInitialized() && ho_Y != null && ho_Y.IsInitialized() && ho_Z != null && ho_Z.IsInitialized()))
            {
                return;
            }
            if (desktop.Length<5)
            {
                desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop).Replace('\\','/')+"/图片保存/";
            }


            if (IsSaveImg|| focus)
            {
                HObject img3;
                HOperatorSet.Compose3(ho_X, ho_Y, ho_Z, out img3);

                if (counts>9)
                {
                    counts = 0;
                }
                string pth = desktop + counts.ToString();
                if (!Directory.Exists(pth))
                {
                    Directory.CreateDirectory(pth);
                }
                counts++;

                HOperatorSet.WriteImage(img3, "tiff", 0, pth + "/" + "DColor");
                if (ho_M != null && ho_M.IsInitialized())
                {
                    HOperatorSet.WriteImage(ho_M, "tiff", 0, pth + "/" + "ho_M");
                }
                img3.Dispose();
            }

            if (false)
            {
                HObject img3;
                HOperatorSet.Compose3(ho_X, ho_Y, ho_Z, out img3);

                string sNowTime = "";
                sNowTime = "./" + savePath + System.DateTime.Now.ToString("yyyy_MM_dd_hh_mm_ss");
                if (!Directory.Exists(sNowTime))
                {
                    Directory.CreateDirectory(sNowTime);
                }
                HOperatorSet.WriteImage(img3, "tiff", 0, sNowTime + "/" + "DColor");
                HOperatorSet.WriteImage(ho_M, "tiff", 0, sNowTime + "/" + "ho_M");
                if (ho_M != null && ho_M.IsInitialized())
                {
                    HOperatorSet.WriteImage(ho_M, "tiff", 0, sNowTime + "/" + "ho_M");
                }

                HOperatorSet.WriteImage(img3, "tiff", 0, "./" + onePath + "DColor");

                if (ho_M != null && ho_M.IsInitialized())
                {
                    HOperatorSet.WriteImage(ho_M, "tiff", 0, "./" + onePath + "ho_M");
                }
                img3.Dispose();
            }

           // HOperatorSet.WriteImage(img3, "tiff", 0, "./" + onePath + "DColor");
            
 
        }
        // 仅显示点云
        private void OnlyplayCould(HObject ho_X, HObject ho_Y, HObject ho_Z)
        {
            
            try
            {
                HOperatorSet.ClearObjectModel3d(hv_ObjectModel3DID);
            }
            catch { }
            HOperatorSet.XyzToObjectModel3d(ho_X, ho_Y, ho_Z, out hv_ObjectModel3DID);
            HTuple PiontStatus = new HTuple();
            HOperatorSet.GetObjectModel3dParams(hv_ObjectModel3DID, "has_points", out PiontStatus);
            if ((int)(new HTuple(PiontStatus.TupleEqual("true"))) == 0)
            {
                return;
            }
            Show3DMode = 4;
            StartDisplay(hWindowID);
        }       
        //显示点云
        public void StartDisplay(HWindow hW)
        {
            HWindowID = hW;
           // 
            if (tdisplay != null && tdisplay.IsAlive)
            {
                Vis3D.bBreak = true;
                //Thread.Sleep(10);
                tdisplay.Join();
                //tdisplay.Abort();
                //Thread.Sleep(5);
            }
            tdisplay = new System.Threading.Thread(new ThreadStart(Display));
            tdisplay.IsBackground = true;
            tdisplay.Start();
        }
        //多线程显示
        public  void Display()
        {
            Vis3D.bBreak = false;
            HTuple hv_PoseOut;
            
            try
            {
                if (Show3DMode == 1)
                {
                    Vis3D.visualize_object_model_3d(HWindowID, hv_ObjectModel3DID, new HTuple(), new HTuple(), new HTuple("colored"), new HTuple(12), out hv_PoseOut);
                }
                else if (Show3DMode == 2)
                {
                    // Vis3D.visualize_object_model_3d(HWindowID, MainWindow.AffineObjectModel3D.TupleConcat(hv_ObjectModel3DPose), new HTuple(), (((((((new HTuple(0)).TupleConcat(0)).TupleConcat(0)).TupleConcat(0)).TupleConcat(0)).TupleConcat(0)).TupleConcat(0)).TupleConcat(hv_PoseItoB), (new HTuple(new HTuple("color_") + (new HTuple(0)).TupleConcat(1))).TupleConcat(((new HTuple("disp_pose_01")).TupleConcat("point_size_01")).TupleConcat("disp_normals")), ((((new HTuple("green")).TupleConcat("blue")).TupleConcat("true")).TupleConcat(10)).TupleConcat("true"), "匹配到模板物体", new HTuple(), hv_Instructions, out hv_PoseOut);
                }
                else if (Show3DMode == 3)
                {
                    Vis3D.visualize_object_model_3d(HWindowID, hv_ObjectModel3DID, new HTuple(), new HTuple(), "colored", 12, out hv_PoseOut);
                }
                else
                {
                    Vis3D.visualize_object_model_3d(HWindowID, hv_ObjectModel3DID, new HTuple(), new HTuple(), "color", "green", out hv_PoseOut);
                }

                try
                {
                    try { HOperatorSet.ClearObjectModel3d(hv_ObjectModel3DID); } catch { }
                }
                catch {}
            }
            catch 
            {
            }
        }


        //启动显示
        public void StartDispImage(HTuple tuple)
        {
            tdisplay = new System.Threading.Thread(ThreadRun);
            tdisplay.IsBackground = true;
            tdisplay.Start(tuple);
        }
        //停止显示
        public void StopDispImage()
        {
            if (tdisplay != null && tdisplay.IsAlive)
            {
                Vis3D.bBreak = true;
                tdisplay.Join();
            }
        }
        //线程循环
        public void ThreadRun(object tuple)
        {
            Vis3D.bBreak = false;
            HTuple hv_PoseOut;
            try
            {
                if (Show3DMode == 1)
                {
                    Vis3D.visualize_object_model_3d(hWindowID, (HTuple)tuple, new HTuple(), new HTuple(), new HTuple("colored"), new HTuple(12), out hv_PoseOut);
                }
                else
                {
                    Vis3D.visualize_object_model_3d(hWindowID, (HTuple)tuple, new HTuple(), new HTuple(), "color", "green", out hv_PoseOut);

                }
                ClearMod3D((HTuple)tuple);
            }
            catch
            {
                ClearMod3D((HTuple)tuple);
            }

        }




        //检查保存路径
        public static bool checkDir(string url)
        {
            try
            {
                if (!Directory.Exists(url))//如果不存在就创建file文件夹　　             　　              
                    Directory.CreateDirectory(url);//创建该文件夹　　            
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }
        //设置显示区域
        public void setImagePart(HObject imag, HWindowControl hwindow)
        {

            if (imag == null)
            {
                return;
            }

            HTuple Size_w, Size_H;
            double Displ_width1, Displ_height1, Displ_width2, Displ_height2;
            HOperatorSet.GetImageSize(imag, out Size_w, out Size_H);
            if (Size_w * hwindow.Height >= Size_H * hwindow.Width)
            {
                double temp = Size_w * hwindow.Height / hwindow.Width;
                Displ_width1 = 0;
                Displ_height1 = (temp - Size_H) / 2;
                Displ_width2 = Size_w;
                Displ_height2 = temp - Displ_height1;
            }
            else
            {
                double temp = Size_H * hwindow.Width / hwindow.Height;
                Displ_width1 = (temp - Size_w) / 2;
                Displ_height1 = 0;
                Displ_width2 = temp - Displ_width1;
                Displ_height2 = Size_H;
            }
            HOperatorSet.SetPart(hwindow.HalconWindow, -Displ_height1, -Displ_width1, Displ_height2, Displ_width2);
        }
    }

    public class VisionTool
    {
        public void gen_tool_3d(HTuple hv_ArrowThickness,
      HTuple hv_ArrowLength, out HTuple hv_OM3DToolOrigin, out HTuple hv_OM3DBase)
        {



            // Local iconic variables 

            // Local control variables 

            HTuple hv_IdentityPose = null, hv_TransXPose = null;
            HTuple hv_OM3DToolXOrigin = null, hv_TransYPose = null;
            HTuple hv_OM3DToolYOrigin = null, hv_TransZPose = null;
            HTuple hv_OM3DToolZOrigin = null, hv_FactorVisBase = null;
            HTuple hv_OM3DBasePlate = null, hv_OM3DBaseX = null, hv_OM3DBaseY = null;
            HTuple hv_OM3DBaseZ = null;
            // Initialize local and output iconic variables 
            //This procedure creates 3D models that represent the tool and the base
            //of the robot.
            //
            if ((int)(new HTuple(hv_ArrowThickness.TupleLessEqual(0))) != 0)
            {
                throw new HalconException("ArrowThickness should be > 0");
            }
            if ((int)(new HTuple(hv_ArrowLength.TupleLessEqual(0))) != 0)
            {
                throw new HalconException("ArrowLength should be > 0");
            }
            HOperatorSet.CreatePose(0, 0, 0, 0, 0, 0, "Rp+T", "gba", "point", out hv_IdentityPose);
            //
            //3D model for the tool.
            HOperatorSet.CreatePose(hv_ArrowLength, 0, 0, 0, 0, 0, "Rp+T", "gba", "point",
                out hv_TransXPose);
            gen_arrow_object_model_3d(hv_ArrowThickness, hv_IdentityPose, hv_TransXPose,
                out hv_OM3DToolXOrigin);
            HOperatorSet.CreatePose(0, hv_ArrowLength, 0, 0, 0, 0, "Rp+T", "gba", "point",
                out hv_TransYPose);
            gen_arrow_object_model_3d(hv_ArrowThickness, hv_IdentityPose, hv_TransYPose,
                out hv_OM3DToolYOrigin);
            HOperatorSet.CreatePose(0, 0, hv_ArrowLength, 0, 0, 0, "Rp+T", "gba", "point",
                out hv_TransZPose);
            gen_arrow_object_model_3d(hv_ArrowThickness, hv_IdentityPose, hv_TransZPose,
                out hv_OM3DToolZOrigin);
            hv_OM3DToolOrigin = new HTuple();
            hv_OM3DToolOrigin = hv_OM3DToolOrigin.TupleConcat(hv_OM3DToolXOrigin);
            hv_OM3DToolOrigin = hv_OM3DToolOrigin.TupleConcat(hv_OM3DToolYOrigin);
            hv_OM3DToolOrigin = hv_OM3DToolOrigin.TupleConcat(hv_OM3DToolZOrigin);
            //
            //3D model for the base.
            hv_FactorVisBase = hv_ArrowThickness * 10;
            HOperatorSet.GenBoxObjectModel3d(hv_IdentityPose, hv_FactorVisBase * 0.5, hv_FactorVisBase * 0.5,
                hv_FactorVisBase / 18, out hv_OM3DBasePlate);
            HOperatorSet.CreatePose(hv_ArrowLength, 0, 0, 0, 0, 0, "Rp+T", "gba", "point",
                out hv_TransXPose);
            gen_arrow_object_model_3d(hv_ArrowThickness, hv_IdentityPose, hv_TransXPose,
                out hv_OM3DBaseX);
            HOperatorSet.CreatePose(0, hv_ArrowLength, 0, 0, 0, 0, "Rp+T", "gba", "point",
                out hv_TransYPose);
            gen_arrow_object_model_3d(hv_ArrowThickness, hv_IdentityPose, hv_TransYPose,
                out hv_OM3DBaseY);
            HOperatorSet.CreatePose(0, 0, hv_ArrowLength, 0, 0, 0, "Rp+T", "gba", "point",
                out hv_TransZPose);
            gen_arrow_object_model_3d(hv_ArrowThickness, hv_IdentityPose, hv_TransZPose,
                out hv_OM3DBaseZ);
            hv_OM3DBase = new HTuple();
            hv_OM3DBase = hv_OM3DBase.TupleConcat(hv_OM3DBaseX);
            hv_OM3DBase = hv_OM3DBase.TupleConcat(hv_OM3DBaseY);
            hv_OM3DBase = hv_OM3DBase.TupleConcat(hv_OM3DBaseZ);
            hv_OM3DBase = hv_OM3DBase.TupleConcat(hv_OM3DBasePlate);

            return;
        }

        public void gen_arrow_object_model_3d(HTuple hv_ArrowThickness, HTuple hv_ArrowStart,
    HTuple hv_ArrowEnd, out HTuple hv_OM3DArrow)
        {



            // Local iconic variables 

            // Local control variables 

            HTuple hv_DirectionVector = null, hv_ArrowLength = null;
            HTuple hv_ConeRadius = null, hv_ConeLength = null, hv_CylinderLength = null;
            HTuple hv_pi = null, hv_X = null, hv_Y = null, hv_Z = null;
            HTuple hv_Index = null, hv_OM3DConeTmp = null, hv_OM3DCone = null;
            HTuple hv_ZZero = null, hv_ZTop = null, hv_OM3DCylinderTmp = null;
            HTuple hv_OM3DCylinder = null, hv_OM3DArrowTmp = null;
            HTuple hv_Scale = null, hv_OriginX = null, hv_OriginY = null;
            HTuple hv_OriginZ = null, hv_TargetX = null, hv_TargetY = null;
            HTuple hv_TargetZ = null, hv_HomMat3D = null;
            // Initialize local and output iconic variables 
            //
            //This procedure draws an arrow that starts at the point ArrowStart and ends at ArrowEnd.
            //
            //Get parameters.
            hv_DirectionVector = (hv_ArrowEnd.TupleSelectRange(0, 2)) - (hv_ArrowStart.TupleSelectRange(
                0, 2));
            hv_ArrowLength = (((((hv_DirectionVector.TupleSelect(0)) * (hv_DirectionVector.TupleSelect(
                0))) + ((hv_DirectionVector.TupleSelect(1)) * (hv_DirectionVector.TupleSelect(
                1)))) + ((hv_DirectionVector.TupleSelect(2)) * (hv_DirectionVector.TupleSelect(
                2))))).TupleSqrt();
            hv_ConeRadius = 2.0 * hv_ArrowThickness;
            hv_ConeLength = ((((2.0 * hv_ConeRadius)).TupleConcat(hv_ArrowLength * 0.9))).TupleMin()
                ;
            hv_CylinderLength = hv_ArrowLength - hv_ConeLength;
            //
            //Create cone.
            hv_pi = (new HTuple(180)).TupleRad();
            hv_X = 0;
            hv_Y = 0;
            hv_Z = hv_CylinderLength + hv_ConeLength;
            HTuple end_val15 = 2 * hv_pi;
            HTuple step_val15 = 0.1;
            for (hv_Index = 0; hv_Index.Continue(end_val15, step_val15); hv_Index = hv_Index.TupleAdd(step_val15))
            {
                hv_X = hv_X.TupleConcat(hv_ConeRadius * (hv_Index.TupleCos()));
                hv_Y = hv_Y.TupleConcat(hv_ConeRadius * (hv_Index.TupleSin()));
                hv_Z = hv_Z.TupleConcat(hv_CylinderLength);
            }
            HOperatorSet.GenObjectModel3dFromPoints(hv_X, hv_Y, hv_Z, out hv_OM3DConeTmp);
            HOperatorSet.ConvexHullObjectModel3d(hv_OM3DConeTmp, out hv_OM3DCone);

            HOperatorSet.ClearObjectModel3d(hv_OM3DConeTmp);
            //
            //Create cylinder.
            hv_X = new HTuple();
            hv_Y = new HTuple();
            HTuple end_val28 = 2 * hv_pi;
            HTuple step_val28 = 0.1;
            for (hv_Index = 0; hv_Index.Continue(end_val28, step_val28); hv_Index = hv_Index.TupleAdd(step_val28))
            {
                hv_X = hv_X.TupleConcat(hv_ArrowThickness * (hv_Index.TupleCos()));
                hv_Y = hv_Y.TupleConcat(hv_ArrowThickness * (hv_Index.TupleSin()));
            }
            HOperatorSet.TupleGenConst(new HTuple(hv_Y.TupleLength()), 0, out hv_ZZero);
            HOperatorSet.TupleGenConst(new HTuple(hv_Y.TupleLength()), hv_CylinderLength,
                out hv_ZTop);
            HOperatorSet.GenObjectModel3dFromPoints(hv_X.TupleConcat(hv_X), hv_Y.TupleConcat(
                hv_Y), hv_ZZero.TupleConcat(hv_ZTop), out hv_OM3DCylinderTmp);
            HOperatorSet.ConvexHullObjectModel3d(hv_OM3DCylinderTmp, out hv_OM3DCylinder);
            HOperatorSet.ClearObjectModel3d(hv_OM3DCylinderTmp);
            //
            //Union cone and cylinder Create arrow.
            HOperatorSet.UnionObjectModel3d(hv_OM3DCone.TupleConcat(hv_OM3DCylinder), "points_surface",
                out hv_OM3DArrowTmp);
            HOperatorSet.ClearObjectModel3d(hv_OM3DCone);
            HOperatorSet.ClearObjectModel3d(hv_OM3DCylinder);
            hv_Scale = hv_CylinderLength / hv_ArrowLength;
            hv_OriginX = new HTuple();
            hv_OriginX[0] = 0;
            hv_OriginX[1] = 0;
            hv_OriginX[2] = 0;
            hv_OriginY = new HTuple();
            hv_OriginY[0] = 0;
            hv_OriginY[1] = 0;
            hv_OriginY[2] = 0;
            hv_OriginZ = new HTuple();
            hv_OriginZ[0] = 0;
            hv_OriginZ = hv_OriginZ.TupleConcat(hv_CylinderLength);
            hv_OriginZ = hv_OriginZ.TupleConcat(hv_ArrowLength);
            hv_TargetX = new HTuple();
            hv_TargetX = hv_TargetX.TupleConcat(hv_ArrowStart.TupleSelect(
                0));
            hv_TargetX = hv_TargetX.TupleConcat((hv_ArrowStart.TupleSelect(0)) + (hv_Scale * (hv_DirectionVector.TupleSelect(
                0))));
            hv_TargetX = hv_TargetX.TupleConcat(hv_ArrowEnd.TupleSelect(0));
            hv_TargetY = new HTuple();
            hv_TargetY = hv_TargetY.TupleConcat(hv_ArrowStart.TupleSelect(
                1));
            hv_TargetY = hv_TargetY.TupleConcat((hv_ArrowStart.TupleSelect(1)) + (hv_Scale * (hv_DirectionVector.TupleSelect(
                1))));
            hv_TargetY = hv_TargetY.TupleConcat(hv_ArrowEnd.TupleSelect(1));
            hv_TargetZ = new HTuple();
            hv_TargetZ = hv_TargetZ.TupleConcat(hv_ArrowStart.TupleSelect(
                2));
            hv_TargetZ = hv_TargetZ.TupleConcat((hv_ArrowStart.TupleSelect(2)) + (hv_Scale * (hv_DirectionVector.TupleSelect(
                2))));
            hv_TargetZ = hv_TargetZ.TupleConcat(hv_ArrowEnd.TupleSelect(2));
            HOperatorSet.VectorToHomMat3d("rigid", hv_OriginX, hv_OriginY, hv_OriginZ, hv_TargetX,
                hv_TargetY, hv_TargetZ, out hv_HomMat3D);
            HOperatorSet.AffineTransObjectModel3d(hv_OM3DArrowTmp, hv_HomMat3D, out hv_OM3DArrow);
            HOperatorSet.ClearObjectModel3d(hv_OM3DArrowTmp);

            return;
        }


        void TransTool(HTuple Pose,HTuple Tool,out HTuple TranTool)
        {
            HOperatorSet.RigidTransObjectModel3d(Tool, Pose, out TranTool);
        }

    }

    public class Match
    {
        
        /// <summary>
        /// 3D模型匹配
        /// </summary>
        /// <param name="ObjectModel3D"></param>
        /// <param name="MatchModel3D"></param>
        /// <param name="MatchData"></param>
        /// <param name="OutPose"></param>
        /// <param name="Match_Score"></param>
        public static void Model3D_Match(HTuple ObjectModel3D,HTuple MatchModel3D,HTuple MatchData,out HTuple[] OutMat3d, out HTuple Match_Score)
        {
            //0 场景采样距离（减小会导致更多的采样点 0.1） 1 采样场景点的分数（0.5，则50％的采样场景点将用作关键点）
            //2 最低分数  3  匹配数量

            //使用模板点云匹配相机拍摄点云并映射到对应位置
            //点云  模板   场景采样距离（减小会导致更多的采样点 0.1）   采样场景点的分数（0.5，则50％的采样场景点将用作关键点）   最低分数

            HTuple Match_Pose, MatchingResultID;
            
            HOperatorSet.FindSurfaceModel(MatchModel3D, ObjectModel3D, MatchData[0].D,
              MatchData[1].D, MatchData[2].D, "false", (new HTuple("scene_normal_computation")).TupleConcat("num_matches").TupleConcat("max_overlap_dist_rel").
              TupleConcat("pose_ref_use_scene_normals").TupleConcat("pose_ref_scoring_dist_rel").TupleConcat("max_gap"),
                (new HTuple("mls")).TupleConcat((int)(MatchData[3].D)).TupleConcat(1.0).TupleConcat("true").TupleConcat(0.05).TupleConcat(30), out Match_Pose, out Match_Score, out MatchingResultID);

            //fast mls  scene_normal_computation    (new HTuple("mls")).TupleConcat((int)(MatchData[3].D))   .TupleConcat("pose_ref_scoring_dist_rel")

            OutMat3d = new HTuple[Match_Score.Length];
            ////细化姿态
            if (false)
            {
                HOperatorSet.RefineSurfaceModelPose(MatchModel3D, ObjectModel3D, Match_Pose, 0, "false", new HTuple(), new HTuple(),
                    out Match_Pose, out Match_Score, out MatchingResultID);
            }
            //获取姿态结果
            for (int i = 0; i < Match_Score.Length; i++)
            {
                HTuple PoseSelect= Match_Pose.TupleSelectRange(7 * i, 7 * (i + 1) - 1);
                HOperatorSet.PoseToHomMat3d(PoseSelect, out OutMat3d[i]);
            }
            HOperatorSet.ClearSurfaceMatchingResult(MatchingResultID);
        }
       
        /// <summary>
        /// 显示转换
        /// </summary>
        /// <param name="ObjectModel3D"></param>
        /// <param name="OutMat3d"></param>
        /// <param name="ObjectModel3DDisp"></param>
        public static void DispModel_Trans(HTuple ObjectModel3D, HTuple[] OutMat3d,out HTuple ObjectModel3DDisp)
        {
            ObjectModel3DDisp = new HTuple();
            for (int i = 0; i < OutMat3d.Length; i++)
            {
                HTuple TempObj;
                HOperatorSet.AffineTransObjectModel3d(ObjectModel3D, OutMat3d[i], out TempObj);
                ObjectModel3DDisp.Append(TempObj);
            }
        }
       
        /// <summary>
        /// 转换抓取坐标 eye_in_hand
        /// </summary>
        /// <param name="Hand_eye_Trans">eye_in_hand 标定 </param>
        /// <param name="RobotCurrentMat3d">机器人当前拍照坐标</param>
        /// <param name="WaitPose">模板准备姿态</param>
        /// <param name="MatchMat3D">点云匹配结果</param>
        /// <param name="RobotPose">机器人抓取姿态xyz</param>
        public static void GetRobotPose(HTuple Hand_eye_Trans,HTuple RobotCurrentMat3d, HTuple WaitPose,HTuple MatchMat3D,out HTuple RobotPose)
        {
            HTuple WatiMat3d, PickMat3D;
            HOperatorSet.PoseToHomMat3d(WaitPose, out WatiMat3d);
            //相机坐标系中抓取坐标
            HOperatorSet.HomMat3dCompose(MatchMat3D, WatiMat3d, out PickMat3D);

            //求转换矩阵的逆矩阵
            HTuple Hand_eye_Inviter;
            HOperatorSet.HomMat3dInvert(Hand_eye_Trans,out Hand_eye_Inviter);

            //机器人抓取坐标
            HTuple Tmp1,Tmp2;
            HOperatorSet.HomMat3dCompose(Hand_eye_Inviter, PickMat3D, out Tmp1);
            HOperatorSet.HomMat3dCompose(RobotCurrentMat3d, Tmp1, out Tmp2);
            HOperatorSet.HomMat3dToPose(Tmp2,out RobotPose);

        }
        /// <summary>
        /// 四元数转换矩阵
        /// </summary>
        /// <param name="Quat">坐标加旋转 长度4</param>
        /// <param name="Mat3d">矩阵</param>
        public static void Quat_ToMat3d(HTuple Quat,out HTuple Mat3d)
        {
            Mat3d = new HTuple();
            if (Quat!=7)
            {
                return;
            }
            HTuple tmp1 = Quat.TupleSelectRange(3, 6); ;
            HTuple tmp2;
            HOperatorSet.QuatToPose(tmp1,out tmp2);
            tmp2[0].D = Quat[0].D;
            tmp2[1].D = Quat[1].D;
            tmp2[2].D = Quat[2].D;
            HOperatorSet.PoseToHomMat3d(tmp2, out Mat3d);
        }
        /// <summary>
        /// 姿态转换为四元数
        /// </summary>
        /// <param name="Pose"></param>
        /// <param name="Quat"></param>
        public static void Pose_ToQuat(HTuple Pose,out HTuple Quat)
        {
            HTuple tmp;
            HOperatorSet.PoseToQuat(Pose,out tmp);
            Quat = Pose.TupleSelectRange(0, 2);
            Quat.Append(tmp);
        }
        
      
    }

    //显示
    public class HalconWindowProcess
    {
        public HTuple hv_ExpDefaultWinHandle;
        public bool bBreak = false;
        HTuple gTerminationButtonLabel;
        HTuple gIsSinglePose;
        HTuple gInfoDecor;
        HTuple gInfoPos;
        HTuple gTitlePos;
        HTuple gTitleDecor;
        HTuple gDispObjOffset;
        HTuple gLabelsDecor;
        HTuple gAlphaDeselected;
        HTuple gUsesOpenGL;

        HTuple ExpGetGlobalVar_gTerminationButtonLabel()
        {
            return gTerminationButtonLabel;
        }
        void ExpSetGlobalVar_gTerminationButtonLabel(HTuple val)
        {
            gTerminationButtonLabel = val;
        }

        HTuple ExpGetGlobalVar_gIsSinglePose()
        {
            return gIsSinglePose;
        }
        void ExpSetGlobalVar_gIsSinglePose(HTuple val)
        {
            gIsSinglePose = val;
        }

        HTuple ExpGetGlobalVar_gInfoDecor()
        {
            return gInfoDecor;
        }
        void ExpSetGlobalVar_gInfoDecor(HTuple val)
        {
            gInfoDecor = val;
        }

        HTuple ExpGetGlobalVar_gInfoPos()
        {
            return gInfoPos;
        }
        void ExpSetGlobalVar_gInfoPos(HTuple val)
        {
            gInfoPos = val;
        }

        HTuple ExpGetGlobalVar_gTitlePos()
        {
            return gTitlePos;
        }
        void ExpSetGlobalVar_gTitlePos(HTuple val)
        {
            gTitlePos = val;
        }

        HTuple ExpGetGlobalVar_gTitleDecor()
        {
            return gTitleDecor;
        }
        void ExpSetGlobalVar_gTitleDecor(HTuple val)
        {
            gTitleDecor = val;
        }

        HTuple ExpGetGlobalVar_gDispObjOffset()
        {
            return gDispObjOffset;
        }
        void ExpSetGlobalVar_gDispObjOffset(HTuple val)
        {
            gDispObjOffset = val;
        }

        HTuple ExpGetGlobalVar_gLabelsDecor()
        {
            return gLabelsDecor;
        }
        void ExpSetGlobalVar_gLabelsDecor(HTuple val)
        {
            gLabelsDecor = val;
        }

        HTuple ExpGetGlobalVar_gAlphaDeselected()
        {
            return gAlphaDeselected;
        }
        void ExpSetGlobalVar_gAlphaDeselected(HTuple val)
        {
            gAlphaDeselected = val;
        }

        HTuple ExpGetGlobalVar_gUsesOpenGL()
        {
            return gUsesOpenGL;
        }
        void ExpSetGlobalVar_gUsesOpenGL(HTuple val)
        {
            gUsesOpenGL = val;
        }

        // Procedures 
        // External procedures 
        // Chapter: Calibration / Camera Parameters
        // Short Description: Generate a camera parameter tuple for an area scan camera with distortions modeled by the division model. 
        public void gen_cam_par_area_scan_division(HTuple hv_Focus, HTuple hv_Kappa, HTuple hv_Sx,
            HTuple hv_Sy, HTuple hv_Cx, HTuple hv_Cy, HTuple hv_ImageWidth, HTuple hv_ImageHeight,
            out HTuple hv_CameraParam)
        {



            // Local iconic variables 
            // Initialize local and output iconic variables 
            //Generate a camera parameter tuple for an area scan camera
            //with distortions modeled by the division model.
            //
            hv_CameraParam = new HTuple();
            hv_CameraParam[0] = "area_scan_division";
            hv_CameraParam = hv_CameraParam.TupleConcat(hv_Focus);
            hv_CameraParam = hv_CameraParam.TupleConcat(hv_Kappa);
            hv_CameraParam = hv_CameraParam.TupleConcat(hv_Sx);
            hv_CameraParam = hv_CameraParam.TupleConcat(hv_Sy);
            hv_CameraParam = hv_CameraParam.TupleConcat(hv_Cx);
            hv_CameraParam = hv_CameraParam.TupleConcat(hv_Cy);
            hv_CameraParam = hv_CameraParam.TupleConcat(hv_ImageWidth);
            hv_CameraParam = hv_CameraParam.TupleConcat(hv_ImageHeight);

            return;
        }


        // Chapter: Graphics / Text
        // Short Description: This procedure writes a text message. 
        public void disp_message(HTuple hv_WindowHandle, HTuple hv_String, HTuple hv_CoordSystem,
            HTuple hv_Row, HTuple hv_Column, HTuple hv_Color, HTuple hv_Box)
        {



            // Local iconic variables 

            // Local control variables 

            HTuple hv_GenParamName = null, hv_GenParamValue = null;
            HTuple hv_Color_COPY_INP_TMP = hv_Color.Clone();
            HTuple hv_Column_COPY_INP_TMP = hv_Column.Clone();
            HTuple hv_CoordSystem_COPY_INP_TMP = hv_CoordSystem.Clone();
            HTuple hv_Row_COPY_INP_TMP = hv_Row.Clone();

            // Initialize local and output iconic variables 
            //This procedure displays text in a graphics window.
            //
            //Input parameters:
            //WindowHandle: The WindowHandle of the graphics window, where
            //   the message should be displayed
            //String: A tuple of strings containing the text message to be displayed
            //CoordSystem: If set to 'window', the text position is given
            //   with respect to the window coordinate system.
            //   If set to 'image', image coordinates are used.
            //   (This may be useful in zoomed images.)
            //Row: The row coordinate of the desired text position
            //   A tuple of values is allowed to display text at different
            //   positions.
            //Column: The column coordinate of the desired text position
            //   A tuple of values is allowed to display text at different
            //   positions.
            //Color: defines the color of the text as string.
            //   If set to [], '' or 'auto' the currently set color is used.
            //   If a tuple of strings is passed, the colors are used cyclically...
            //   - if |Row| == |Column| == 1: for each new textline
            //   = else for each text position.
            //Box: If Box[0] is set to 'true', the text is written within an orange box.
            //     If set to' false', no box is displayed.
            //     If set to a color string (e.g. 'white', '#FF00CC', etc.),
            //       the text is written in a box of that color.
            //     An optional second value for Box (Box[1]) controls if a shadow is displayed:
            //       'true' -> display a shadow in a default color
            //       'false' -> display no shadow
            //       otherwise -> use given string as color string for the shadow color
            //
            //It is possible to display multiple text strings in a single call.
            //In this case, some restrictions apply:
            //- Multiple text positions can be defined by specifying a tuple
            //  with multiple Row and/or Column coordinates, i.e.:
            //  - |Row| == n, |Column| == n
            //  - |Row| == n, |Column| == 1
            //  - |Row| == 1, |Column| == n
            //- If |Row| == |Column| == 1,
            //  each element of String is display in a new textline.
            //- If multiple positions or specified, the number of Strings
            //  must match the number of positions, i.e.:
            //  - Either |String| == n (each string is displayed at the
            //                          corresponding position),
            //  - or     |String| == 1 (The string is displayed n times).
            //
            //
            //Convert the parameters for disp_text.
            if ((int)((new HTuple(hv_Row_COPY_INP_TMP.TupleEqual(new HTuple()))).TupleOr(
                new HTuple(hv_Column_COPY_INP_TMP.TupleEqual(new HTuple())))) != 0)
            {

                return;
            }
            if ((int)(new HTuple(hv_Row_COPY_INP_TMP.TupleEqual(-1))) != 0)
            {
                hv_Row_COPY_INP_TMP = 12;
            }
            if ((int)(new HTuple(hv_Column_COPY_INP_TMP.TupleEqual(-1))) != 0)
            {
                hv_Column_COPY_INP_TMP = 12;
            }
            //
            //Convert the parameter Box to generic parameters.
            hv_GenParamName = new HTuple();
            hv_GenParamValue = new HTuple();
            if ((int)(new HTuple((new HTuple(hv_Box.TupleLength())).TupleGreater(0))) != 0)
            {
                if ((int)(new HTuple(((hv_Box.TupleSelect(0))).TupleEqual("false"))) != 0)
                {
                    //Display no box
                    hv_GenParamName = hv_GenParamName.TupleConcat("box");
                    hv_GenParamValue = hv_GenParamValue.TupleConcat("false");
                }
                else if ((int)(new HTuple(((hv_Box.TupleSelect(0))).TupleNotEqual("true"))) != 0)
                {
                    //Set a color other than the default.
                    hv_GenParamName = hv_GenParamName.TupleConcat("box_color");
                    hv_GenParamValue = hv_GenParamValue.TupleConcat(hv_Box.TupleSelect(0));
                }
            }
            if ((int)(new HTuple((new HTuple(hv_Box.TupleLength())).TupleGreater(1))) != 0)
            {
                if ((int)(new HTuple(((hv_Box.TupleSelect(1))).TupleEqual("false"))) != 0)
                {
                    //Display no shadow.
                    hv_GenParamName = hv_GenParamName.TupleConcat("shadow");
                    hv_GenParamValue = hv_GenParamValue.TupleConcat("false");
                }
                else if ((int)(new HTuple(((hv_Box.TupleSelect(1))).TupleNotEqual("true"))) != 0)
                {
                    //Set a shadow color other than the default.
                    hv_GenParamName = hv_GenParamName.TupleConcat("shadow_color");
                    hv_GenParamValue = hv_GenParamValue.TupleConcat(hv_Box.TupleSelect(1));
                }
            }
            //Restore default CoordSystem behavior.
            if ((int)(new HTuple(hv_CoordSystem_COPY_INP_TMP.TupleNotEqual("window"))) != 0)
            {
                hv_CoordSystem_COPY_INP_TMP = "image";
            }
            //
            if ((int)(new HTuple(hv_Color_COPY_INP_TMP.TupleEqual(""))) != 0)
            {
                //disp_text does not accept an empty string for Color.
                hv_Color_COPY_INP_TMP = new HTuple();
            }
            //
            hv_ExpDefaultWinHandle = hv_WindowHandle;
            HOperatorSet.DispText(hv_ExpDefaultWinHandle, hv_String, hv_CoordSystem_COPY_INP_TMP,
                hv_Row_COPY_INP_TMP, hv_Column_COPY_INP_TMP, hv_Color_COPY_INP_TMP, hv_GenParamName,
                hv_GenParamValue);

            return;
        }

        // Chapter: Calibration / Camera Parameters
        // Short Description: Get the names of the parameters in a camera parameter tuple. 
        public void get_cam_par_names(HTuple hv_CameraParam, out HTuple hv_CameraType,
            out HTuple hv_ParamNames)
        {



            // Local iconic variables 

            // Local control variables 

            HTuple hv_CameraParamAreaScanDivision = null;
            HTuple hv_CameraParamAreaScanPolynomial = null, hv_CameraParamAreaScanTelecentricDivision = null;
            HTuple hv_CameraParamAreaScanTelecentricPolynomial = null;
            HTuple hv_CameraParamAreaScanTiltDivision = null, hv_CameraParamAreaScanTiltPolynomial = null;
            HTuple hv_CameraParamAreaScanImageSideTelecentricTiltDivision = null;
            HTuple hv_CameraParamAreaScanImageSideTelecentricTiltPolynomial = null;
            HTuple hv_CameraParamAreaScanBilateralTelecentricTiltDivision = null;
            HTuple hv_CameraParamAreaScanBilateralTelecentricTiltPolynomial = null;
            HTuple hv_CameraParamAreaScanObjectSideTelecentricTiltDivision = null;
            HTuple hv_CameraParamAreaScanObjectSideTelecentricTiltPolynomial = null;
            HTuple hv_CameraParamLinesScan = null, hv_CameraParamAreaScanTiltDivisionLegacy = null;
            HTuple hv_CameraParamAreaScanTiltPolynomialLegacy = null;
            HTuple hv_CameraParamAreaScanTelecentricDivisionLegacy = null;
            HTuple hv_CameraParamAreaScanTelecentricPolynomialLegacy = null;
            HTuple hv_CameraParamAreaScanBilateralTelecentricTiltDivisionLegacy = null;
            HTuple hv_CameraParamAreaScanBilateralTelecentricTiltPolynomialLegacy = null;
            // Initialize local and output iconic variables 
            hv_CameraType = new HTuple();
            hv_ParamNames = new HTuple();
            //get_cam_par_names returns for each element in the camera
            //parameter tuple that is passed in CameraParam the name
            //of the respective camera parameter. The parameter names
            //are returned in ParamNames. Additionally, the camera
            //type is returned in CameraType. Alternatively, instead of
            //the camera parameters, the camera type can be passed in
            //CameraParam in form of one of the following strings:
            //  - 'area_scan_division'
            //  - 'area_scan_polynomial'
            //  - 'area_scan_tilt_division'
            //  - 'area_scan_tilt_polynomial'
            //  - 'area_scan_telecentric_division'
            //  - 'area_scan_telecentric_polynomial'
            //  - 'area_scan_tilt_bilateral_telecentric_division'
            //  - 'area_scan_tilt_bilateral_telecentric_polynomial'
            //  - 'area_scan_tilt_object_side_telecentric_division'
            //  - 'area_scan_tilt_object_side_telecentric_polynomial'
            //  - 'line_scan'
            //
            hv_CameraParamAreaScanDivision = new HTuple();
            hv_CameraParamAreaScanDivision[0] = "focus";
            hv_CameraParamAreaScanDivision[1] = "kappa";
            hv_CameraParamAreaScanDivision[2] = "sx";
            hv_CameraParamAreaScanDivision[3] = "sy";
            hv_CameraParamAreaScanDivision[4] = "cx";
            hv_CameraParamAreaScanDivision[5] = "cy";
            hv_CameraParamAreaScanDivision[6] = "image_width";
            hv_CameraParamAreaScanDivision[7] = "image_height";
            hv_CameraParamAreaScanPolynomial = new HTuple();
            hv_CameraParamAreaScanPolynomial[0] = "focus";
            hv_CameraParamAreaScanPolynomial[1] = "k1";
            hv_CameraParamAreaScanPolynomial[2] = "k2";
            hv_CameraParamAreaScanPolynomial[3] = "k3";
            hv_CameraParamAreaScanPolynomial[4] = "p1";
            hv_CameraParamAreaScanPolynomial[5] = "p2";
            hv_CameraParamAreaScanPolynomial[6] = "sx";
            hv_CameraParamAreaScanPolynomial[7] = "sy";
            hv_CameraParamAreaScanPolynomial[8] = "cx";
            hv_CameraParamAreaScanPolynomial[9] = "cy";
            hv_CameraParamAreaScanPolynomial[10] = "image_width";
            hv_CameraParamAreaScanPolynomial[11] = "image_height";
            hv_CameraParamAreaScanTelecentricDivision = new HTuple();
            hv_CameraParamAreaScanTelecentricDivision[0] = "magnification";
            hv_CameraParamAreaScanTelecentricDivision[1] = "kappa";
            hv_CameraParamAreaScanTelecentricDivision[2] = "sx";
            hv_CameraParamAreaScanTelecentricDivision[3] = "sy";
            hv_CameraParamAreaScanTelecentricDivision[4] = "cx";
            hv_CameraParamAreaScanTelecentricDivision[5] = "cy";
            hv_CameraParamAreaScanTelecentricDivision[6] = "image_width";
            hv_CameraParamAreaScanTelecentricDivision[7] = "image_height";
            hv_CameraParamAreaScanTelecentricPolynomial = new HTuple();
            hv_CameraParamAreaScanTelecentricPolynomial[0] = "magnification";
            hv_CameraParamAreaScanTelecentricPolynomial[1] = "k1";
            hv_CameraParamAreaScanTelecentricPolynomial[2] = "k2";
            hv_CameraParamAreaScanTelecentricPolynomial[3] = "k3";
            hv_CameraParamAreaScanTelecentricPolynomial[4] = "p1";
            hv_CameraParamAreaScanTelecentricPolynomial[5] = "p2";
            hv_CameraParamAreaScanTelecentricPolynomial[6] = "sx";
            hv_CameraParamAreaScanTelecentricPolynomial[7] = "sy";
            hv_CameraParamAreaScanTelecentricPolynomial[8] = "cx";
            hv_CameraParamAreaScanTelecentricPolynomial[9] = "cy";
            hv_CameraParamAreaScanTelecentricPolynomial[10] = "image_width";
            hv_CameraParamAreaScanTelecentricPolynomial[11] = "image_height";
            hv_CameraParamAreaScanTiltDivision = new HTuple();
            hv_CameraParamAreaScanTiltDivision[0] = "focus";
            hv_CameraParamAreaScanTiltDivision[1] = "kappa";
            hv_CameraParamAreaScanTiltDivision[2] = "image_plane_dist";
            hv_CameraParamAreaScanTiltDivision[3] = "tilt";
            hv_CameraParamAreaScanTiltDivision[4] = "rot";
            hv_CameraParamAreaScanTiltDivision[5] = "sx";
            hv_CameraParamAreaScanTiltDivision[6] = "sy";
            hv_CameraParamAreaScanTiltDivision[7] = "cx";
            hv_CameraParamAreaScanTiltDivision[8] = "cy";
            hv_CameraParamAreaScanTiltDivision[9] = "image_width";
            hv_CameraParamAreaScanTiltDivision[10] = "image_height";
            hv_CameraParamAreaScanTiltPolynomial = new HTuple();
            hv_CameraParamAreaScanTiltPolynomial[0] = "focus";
            hv_CameraParamAreaScanTiltPolynomial[1] = "k1";
            hv_CameraParamAreaScanTiltPolynomial[2] = "k2";
            hv_CameraParamAreaScanTiltPolynomial[3] = "k3";
            hv_CameraParamAreaScanTiltPolynomial[4] = "p1";
            hv_CameraParamAreaScanTiltPolynomial[5] = "p2";
            hv_CameraParamAreaScanTiltPolynomial[6] = "image_plane_dist";
            hv_CameraParamAreaScanTiltPolynomial[7] = "tilt";
            hv_CameraParamAreaScanTiltPolynomial[8] = "rot";
            hv_CameraParamAreaScanTiltPolynomial[9] = "sx";
            hv_CameraParamAreaScanTiltPolynomial[10] = "sy";
            hv_CameraParamAreaScanTiltPolynomial[11] = "cx";
            hv_CameraParamAreaScanTiltPolynomial[12] = "cy";
            hv_CameraParamAreaScanTiltPolynomial[13] = "image_width";
            hv_CameraParamAreaScanTiltPolynomial[14] = "image_height";
            hv_CameraParamAreaScanImageSideTelecentricTiltDivision = new HTuple();
            hv_CameraParamAreaScanImageSideTelecentricTiltDivision[0] = "focus";
            hv_CameraParamAreaScanImageSideTelecentricTiltDivision[1] = "kappa";
            hv_CameraParamAreaScanImageSideTelecentricTiltDivision[2] = "tilt";
            hv_CameraParamAreaScanImageSideTelecentricTiltDivision[3] = "rot";
            hv_CameraParamAreaScanImageSideTelecentricTiltDivision[4] = "sx";
            hv_CameraParamAreaScanImageSideTelecentricTiltDivision[5] = "sy";
            hv_CameraParamAreaScanImageSideTelecentricTiltDivision[6] = "cx";
            hv_CameraParamAreaScanImageSideTelecentricTiltDivision[7] = "cy";
            hv_CameraParamAreaScanImageSideTelecentricTiltDivision[8] = "image_width";
            hv_CameraParamAreaScanImageSideTelecentricTiltDivision[9] = "image_height";
            hv_CameraParamAreaScanImageSideTelecentricTiltPolynomial = new HTuple();
            hv_CameraParamAreaScanImageSideTelecentricTiltPolynomial[0] = "focus";
            hv_CameraParamAreaScanImageSideTelecentricTiltPolynomial[1] = "k1";
            hv_CameraParamAreaScanImageSideTelecentricTiltPolynomial[2] = "k2";
            hv_CameraParamAreaScanImageSideTelecentricTiltPolynomial[3] = "k3";
            hv_CameraParamAreaScanImageSideTelecentricTiltPolynomial[4] = "p1";
            hv_CameraParamAreaScanImageSideTelecentricTiltPolynomial[5] = "p2";
            hv_CameraParamAreaScanImageSideTelecentricTiltPolynomial[6] = "tilt";
            hv_CameraParamAreaScanImageSideTelecentricTiltPolynomial[7] = "rot";
            hv_CameraParamAreaScanImageSideTelecentricTiltPolynomial[8] = "sx";
            hv_CameraParamAreaScanImageSideTelecentricTiltPolynomial[9] = "sy";
            hv_CameraParamAreaScanImageSideTelecentricTiltPolynomial[10] = "cx";
            hv_CameraParamAreaScanImageSideTelecentricTiltPolynomial[11] = "cy";
            hv_CameraParamAreaScanImageSideTelecentricTiltPolynomial[12] = "image_width";
            hv_CameraParamAreaScanImageSideTelecentricTiltPolynomial[13] = "image_height";
            hv_CameraParamAreaScanBilateralTelecentricTiltDivision = new HTuple();
            hv_CameraParamAreaScanBilateralTelecentricTiltDivision[0] = "magnification";
            hv_CameraParamAreaScanBilateralTelecentricTiltDivision[1] = "kappa";
            hv_CameraParamAreaScanBilateralTelecentricTiltDivision[2] = "tilt";
            hv_CameraParamAreaScanBilateralTelecentricTiltDivision[3] = "rot";
            hv_CameraParamAreaScanBilateralTelecentricTiltDivision[4] = "sx";
            hv_CameraParamAreaScanBilateralTelecentricTiltDivision[5] = "sy";
            hv_CameraParamAreaScanBilateralTelecentricTiltDivision[6] = "cx";
            hv_CameraParamAreaScanBilateralTelecentricTiltDivision[7] = "cy";
            hv_CameraParamAreaScanBilateralTelecentricTiltDivision[8] = "image_width";
            hv_CameraParamAreaScanBilateralTelecentricTiltDivision[9] = "image_height";
            hv_CameraParamAreaScanBilateralTelecentricTiltPolynomial = new HTuple();
            hv_CameraParamAreaScanBilateralTelecentricTiltPolynomial[0] = "magnification";
            hv_CameraParamAreaScanBilateralTelecentricTiltPolynomial[1] = "k1";
            hv_CameraParamAreaScanBilateralTelecentricTiltPolynomial[2] = "k2";
            hv_CameraParamAreaScanBilateralTelecentricTiltPolynomial[3] = "k3";
            hv_CameraParamAreaScanBilateralTelecentricTiltPolynomial[4] = "p1";
            hv_CameraParamAreaScanBilateralTelecentricTiltPolynomial[5] = "p2";
            hv_CameraParamAreaScanBilateralTelecentricTiltPolynomial[6] = "tilt";
            hv_CameraParamAreaScanBilateralTelecentricTiltPolynomial[7] = "rot";
            hv_CameraParamAreaScanBilateralTelecentricTiltPolynomial[8] = "sx";
            hv_CameraParamAreaScanBilateralTelecentricTiltPolynomial[9] = "sy";
            hv_CameraParamAreaScanBilateralTelecentricTiltPolynomial[10] = "cx";
            hv_CameraParamAreaScanBilateralTelecentricTiltPolynomial[11] = "cy";
            hv_CameraParamAreaScanBilateralTelecentricTiltPolynomial[12] = "image_width";
            hv_CameraParamAreaScanBilateralTelecentricTiltPolynomial[13] = "image_height";
            hv_CameraParamAreaScanObjectSideTelecentricTiltDivision = new HTuple();
            hv_CameraParamAreaScanObjectSideTelecentricTiltDivision[0] = "magnification";
            hv_CameraParamAreaScanObjectSideTelecentricTiltDivision[1] = "kappa";
            hv_CameraParamAreaScanObjectSideTelecentricTiltDivision[2] = "image_plane_dist";
            hv_CameraParamAreaScanObjectSideTelecentricTiltDivision[3] = "tilt";
            hv_CameraParamAreaScanObjectSideTelecentricTiltDivision[4] = "rot";
            hv_CameraParamAreaScanObjectSideTelecentricTiltDivision[5] = "sx";
            hv_CameraParamAreaScanObjectSideTelecentricTiltDivision[6] = "sy";
            hv_CameraParamAreaScanObjectSideTelecentricTiltDivision[7] = "cx";
            hv_CameraParamAreaScanObjectSideTelecentricTiltDivision[8] = "cy";
            hv_CameraParamAreaScanObjectSideTelecentricTiltDivision[9] = "image_width";
            hv_CameraParamAreaScanObjectSideTelecentricTiltDivision[10] = "image_height";
            hv_CameraParamAreaScanObjectSideTelecentricTiltPolynomial = new HTuple();
            hv_CameraParamAreaScanObjectSideTelecentricTiltPolynomial[0] = "magnification";
            hv_CameraParamAreaScanObjectSideTelecentricTiltPolynomial[1] = "k1";
            hv_CameraParamAreaScanObjectSideTelecentricTiltPolynomial[2] = "k2";
            hv_CameraParamAreaScanObjectSideTelecentricTiltPolynomial[3] = "k3";
            hv_CameraParamAreaScanObjectSideTelecentricTiltPolynomial[4] = "p1";
            hv_CameraParamAreaScanObjectSideTelecentricTiltPolynomial[5] = "p2";
            hv_CameraParamAreaScanObjectSideTelecentricTiltPolynomial[6] = "image_plane_dist";
            hv_CameraParamAreaScanObjectSideTelecentricTiltPolynomial[7] = "tilt";
            hv_CameraParamAreaScanObjectSideTelecentricTiltPolynomial[8] = "rot";
            hv_CameraParamAreaScanObjectSideTelecentricTiltPolynomial[9] = "sx";
            hv_CameraParamAreaScanObjectSideTelecentricTiltPolynomial[10] = "sy";
            hv_CameraParamAreaScanObjectSideTelecentricTiltPolynomial[11] = "cx";
            hv_CameraParamAreaScanObjectSideTelecentricTiltPolynomial[12] = "cy";
            hv_CameraParamAreaScanObjectSideTelecentricTiltPolynomial[13] = "image_width";
            hv_CameraParamAreaScanObjectSideTelecentricTiltPolynomial[14] = "image_height";
            hv_CameraParamLinesScan = new HTuple();
            hv_CameraParamLinesScan[0] = "focus";
            hv_CameraParamLinesScan[1] = "kappa";
            hv_CameraParamLinesScan[2] = "sx";
            hv_CameraParamLinesScan[3] = "sy";
            hv_CameraParamLinesScan[4] = "cx";
            hv_CameraParamLinesScan[5] = "cy";
            hv_CameraParamLinesScan[6] = "image_width";
            hv_CameraParamLinesScan[7] = "image_height";
            hv_CameraParamLinesScan[8] = "vx";
            hv_CameraParamLinesScan[9] = "vy";
            hv_CameraParamLinesScan[10] = "vz";
            //Legacy parameter names
            hv_CameraParamAreaScanTiltDivisionLegacy = new HTuple();
            hv_CameraParamAreaScanTiltDivisionLegacy[0] = "focus";
            hv_CameraParamAreaScanTiltDivisionLegacy[1] = "kappa";
            hv_CameraParamAreaScanTiltDivisionLegacy[2] = "tilt";
            hv_CameraParamAreaScanTiltDivisionLegacy[3] = "rot";
            hv_CameraParamAreaScanTiltDivisionLegacy[4] = "sx";
            hv_CameraParamAreaScanTiltDivisionLegacy[5] = "sy";
            hv_CameraParamAreaScanTiltDivisionLegacy[6] = "cx";
            hv_CameraParamAreaScanTiltDivisionLegacy[7] = "cy";
            hv_CameraParamAreaScanTiltDivisionLegacy[8] = "image_width";
            hv_CameraParamAreaScanTiltDivisionLegacy[9] = "image_height";
            hv_CameraParamAreaScanTiltPolynomialLegacy = new HTuple();
            hv_CameraParamAreaScanTiltPolynomialLegacy[0] = "focus";
            hv_CameraParamAreaScanTiltPolynomialLegacy[1] = "k1";
            hv_CameraParamAreaScanTiltPolynomialLegacy[2] = "k2";
            hv_CameraParamAreaScanTiltPolynomialLegacy[3] = "k3";
            hv_CameraParamAreaScanTiltPolynomialLegacy[4] = "p1";
            hv_CameraParamAreaScanTiltPolynomialLegacy[5] = "p2";
            hv_CameraParamAreaScanTiltPolynomialLegacy[6] = "tilt";
            hv_CameraParamAreaScanTiltPolynomialLegacy[7] = "rot";
            hv_CameraParamAreaScanTiltPolynomialLegacy[8] = "sx";
            hv_CameraParamAreaScanTiltPolynomialLegacy[9] = "sy";
            hv_CameraParamAreaScanTiltPolynomialLegacy[10] = "cx";
            hv_CameraParamAreaScanTiltPolynomialLegacy[11] = "cy";
            hv_CameraParamAreaScanTiltPolynomialLegacy[12] = "image_width";
            hv_CameraParamAreaScanTiltPolynomialLegacy[13] = "image_height";
            hv_CameraParamAreaScanTelecentricDivisionLegacy = new HTuple();
            hv_CameraParamAreaScanTelecentricDivisionLegacy[0] = "focus";
            hv_CameraParamAreaScanTelecentricDivisionLegacy[1] = "kappa";
            hv_CameraParamAreaScanTelecentricDivisionLegacy[2] = "sx";
            hv_CameraParamAreaScanTelecentricDivisionLegacy[3] = "sy";
            hv_CameraParamAreaScanTelecentricDivisionLegacy[4] = "cx";
            hv_CameraParamAreaScanTelecentricDivisionLegacy[5] = "cy";
            hv_CameraParamAreaScanTelecentricDivisionLegacy[6] = "image_width";
            hv_CameraParamAreaScanTelecentricDivisionLegacy[7] = "image_height";
            hv_CameraParamAreaScanTelecentricPolynomialLegacy = new HTuple();
            hv_CameraParamAreaScanTelecentricPolynomialLegacy[0] = "focus";
            hv_CameraParamAreaScanTelecentricPolynomialLegacy[1] = "k1";
            hv_CameraParamAreaScanTelecentricPolynomialLegacy[2] = "k2";
            hv_CameraParamAreaScanTelecentricPolynomialLegacy[3] = "k3";
            hv_CameraParamAreaScanTelecentricPolynomialLegacy[4] = "p1";
            hv_CameraParamAreaScanTelecentricPolynomialLegacy[5] = "p2";
            hv_CameraParamAreaScanTelecentricPolynomialLegacy[6] = "sx";
            hv_CameraParamAreaScanTelecentricPolynomialLegacy[7] = "sy";
            hv_CameraParamAreaScanTelecentricPolynomialLegacy[8] = "cx";
            hv_CameraParamAreaScanTelecentricPolynomialLegacy[9] = "cy";
            hv_CameraParamAreaScanTelecentricPolynomialLegacy[10] = "image_width";
            hv_CameraParamAreaScanTelecentricPolynomialLegacy[11] = "image_height";
            hv_CameraParamAreaScanBilateralTelecentricTiltDivisionLegacy = new HTuple();
            hv_CameraParamAreaScanBilateralTelecentricTiltDivisionLegacy[0] = "focus";
            hv_CameraParamAreaScanBilateralTelecentricTiltDivisionLegacy[1] = "kappa";
            hv_CameraParamAreaScanBilateralTelecentricTiltDivisionLegacy[2] = "tilt";
            hv_CameraParamAreaScanBilateralTelecentricTiltDivisionLegacy[3] = "rot";
            hv_CameraParamAreaScanBilateralTelecentricTiltDivisionLegacy[4] = "sx";
            hv_CameraParamAreaScanBilateralTelecentricTiltDivisionLegacy[5] = "sy";
            hv_CameraParamAreaScanBilateralTelecentricTiltDivisionLegacy[6] = "cx";
            hv_CameraParamAreaScanBilateralTelecentricTiltDivisionLegacy[7] = "cy";
            hv_CameraParamAreaScanBilateralTelecentricTiltDivisionLegacy[8] = "image_width";
            hv_CameraParamAreaScanBilateralTelecentricTiltDivisionLegacy[9] = "image_height";
            hv_CameraParamAreaScanBilateralTelecentricTiltPolynomialLegacy = new HTuple();
            hv_CameraParamAreaScanBilateralTelecentricTiltPolynomialLegacy[0] = "focus";
            hv_CameraParamAreaScanBilateralTelecentricTiltPolynomialLegacy[1] = "k1";
            hv_CameraParamAreaScanBilateralTelecentricTiltPolynomialLegacy[2] = "k2";
            hv_CameraParamAreaScanBilateralTelecentricTiltPolynomialLegacy[3] = "k3";
            hv_CameraParamAreaScanBilateralTelecentricTiltPolynomialLegacy[4] = "p1";
            hv_CameraParamAreaScanBilateralTelecentricTiltPolynomialLegacy[5] = "p2";
            hv_CameraParamAreaScanBilateralTelecentricTiltPolynomialLegacy[6] = "tilt";
            hv_CameraParamAreaScanBilateralTelecentricTiltPolynomialLegacy[7] = "rot";
            hv_CameraParamAreaScanBilateralTelecentricTiltPolynomialLegacy[8] = "sx";
            hv_CameraParamAreaScanBilateralTelecentricTiltPolynomialLegacy[9] = "sy";
            hv_CameraParamAreaScanBilateralTelecentricTiltPolynomialLegacy[10] = "cx";
            hv_CameraParamAreaScanBilateralTelecentricTiltPolynomialLegacy[11] = "cy";
            hv_CameraParamAreaScanBilateralTelecentricTiltPolynomialLegacy[12] = "image_width";
            hv_CameraParamAreaScanBilateralTelecentricTiltPolynomialLegacy[13] = "image_height";
            //
            //If the camera type is passed in CameraParam
            if ((int)((new HTuple((new HTuple(hv_CameraParam.TupleLength())).TupleEqual(1))).TupleAnd(
                ((hv_CameraParam.TupleSelect(0))).TupleIsString())) != 0)
            {
                hv_CameraType = hv_CameraParam.TupleSelect(0);
                if ((int)(new HTuple(hv_CameraType.TupleEqual("area_scan_division"))) != 0)
                {
                    hv_ParamNames = new HTuple();
                    hv_ParamNames[0] = "camera_type";
                    hv_ParamNames = hv_ParamNames.TupleConcat(hv_CameraParamAreaScanDivision);
                }
                else if ((int)(new HTuple(hv_CameraType.TupleEqual("area_scan_polynomial"))) != 0)
                {
                    hv_ParamNames = new HTuple();
                    hv_ParamNames[0] = "camera_type";
                    hv_ParamNames = hv_ParamNames.TupleConcat(hv_CameraParamAreaScanPolynomial);
                }
                else if ((int)(new HTuple(hv_CameraType.TupleEqual("area_scan_telecentric_division"))) != 0)
                {
                    hv_ParamNames = new HTuple();
                    hv_ParamNames[0] = "camera_type";
                    hv_ParamNames = hv_ParamNames.TupleConcat(hv_CameraParamAreaScanTelecentricDivision);
                }
                else if ((int)(new HTuple(hv_CameraType.TupleEqual("area_scan_telecentric_polynomial"))) != 0)
                {
                    hv_ParamNames = new HTuple();
                    hv_ParamNames[0] = "camera_type";
                    hv_ParamNames = hv_ParamNames.TupleConcat(hv_CameraParamAreaScanTelecentricPolynomial);
                }
                else if ((int)(new HTuple(hv_CameraType.TupleEqual("area_scan_tilt_division"))) != 0)
                {
                    hv_ParamNames = new HTuple();
                    hv_ParamNames[0] = "camera_type";
                    hv_ParamNames = hv_ParamNames.TupleConcat(hv_CameraParamAreaScanTiltDivision);
                }
                else if ((int)(new HTuple(hv_CameraType.TupleEqual("area_scan_tilt_polynomial"))) != 0)
                {
                    hv_ParamNames = new HTuple();
                    hv_ParamNames[0] = "camera_type";
                    hv_ParamNames = hv_ParamNames.TupleConcat(hv_CameraParamAreaScanTiltPolynomial);
                }
                else if ((int)(new HTuple(hv_CameraType.TupleEqual("area_scan_tilt_image_side_telecentric_division"))) != 0)
                {
                    hv_ParamNames = new HTuple();
                    hv_ParamNames[0] = "camera_type";
                    hv_ParamNames = hv_ParamNames.TupleConcat(hv_CameraParamAreaScanImageSideTelecentricTiltDivision);
                }
                else if ((int)(new HTuple(hv_CameraType.TupleEqual("area_scan_tilt_image_side_telecentric_polynomial"))) != 0)
                {
                    hv_ParamNames = new HTuple();
                    hv_ParamNames[0] = "camera_type";
                    hv_ParamNames = hv_ParamNames.TupleConcat(hv_CameraParamAreaScanImageSideTelecentricTiltPolynomial);
                }
                else if ((int)(new HTuple(hv_CameraType.TupleEqual("area_scan_tilt_bilateral_telecentric_division"))) != 0)
                {
                    hv_ParamNames = new HTuple();
                    hv_ParamNames[0] = "camera_type";
                    hv_ParamNames = hv_ParamNames.TupleConcat(hv_CameraParamAreaScanBilateralTelecentricTiltDivision);
                }
                else if ((int)(new HTuple(hv_CameraType.TupleEqual("area_scan_tilt_bilateral_telecentric_polynomial"))) != 0)
                {
                    hv_ParamNames = new HTuple();
                    hv_ParamNames[0] = "camera_type";
                    hv_ParamNames = hv_ParamNames.TupleConcat(hv_CameraParamAreaScanBilateralTelecentricTiltPolynomial);
                }
                else if ((int)(new HTuple(hv_CameraType.TupleEqual("area_scan_tilt_object_side_telecentric_division"))) != 0)
                {
                    hv_ParamNames = new HTuple();
                    hv_ParamNames[0] = "camera_type";
                    hv_ParamNames = hv_ParamNames.TupleConcat(hv_CameraParamAreaScanObjectSideTelecentricTiltDivision);
                }
                else if ((int)(new HTuple(hv_CameraType.TupleEqual("area_scan_tilt_object_side_telecentric_polynomial"))) != 0)
                {
                    hv_ParamNames = new HTuple();
                    hv_ParamNames[0] = "camera_type";
                    hv_ParamNames = hv_ParamNames.TupleConcat(hv_CameraParamAreaScanObjectSideTelecentricTiltPolynomial);
                }
                else if ((int)(new HTuple(hv_CameraType.TupleEqual("line_scan"))) != 0)
                {
                    hv_ParamNames = new HTuple();
                    hv_ParamNames[0] = "camera_type";
                    hv_ParamNames = hv_ParamNames.TupleConcat(hv_CameraParamLinesScan);
                }
                else
                {
                    throw new HalconException(("Unknown camera type '" + hv_CameraType) + "' passed in CameraParam.");
                }

                return;
            }
            //
            //If the camera parameters are passed in CameraParam
            if ((int)(((((hv_CameraParam.TupleSelect(0))).TupleIsString())).TupleNot()) != 0)
            {
                //Format of camera parameters for HALCON 12 and earlier
                switch ((new HTuple(hv_CameraParam.TupleLength()
                    )).I)
                {
                    //
                    //Area Scan
                    case 8:
                        //CameraType: 'area_scan_division' or 'area_scan_telecentric_division'
                        if ((int)(new HTuple(((hv_CameraParam.TupleSelect(0))).TupleNotEqual(0.0))) != 0)
                        {
                            hv_ParamNames = hv_CameraParamAreaScanDivision.Clone();
                            hv_CameraType = "area_scan_division";
                        }
                        else
                        {
                            hv_ParamNames = hv_CameraParamAreaScanTelecentricDivisionLegacy.Clone();
                            hv_CameraType = "area_scan_telecentric_division";
                        }
                        break;
                    case 10:
                        //CameraType: 'area_scan_tilt_division' or 'area_scan_telecentric_tilt_division'
                        if ((int)(new HTuple(((hv_CameraParam.TupleSelect(0))).TupleNotEqual(0.0))) != 0)
                        {
                            hv_ParamNames = hv_CameraParamAreaScanTiltDivisionLegacy.Clone();
                            hv_CameraType = "area_scan_tilt_division";
                        }
                        else
                        {
                            hv_ParamNames = hv_CameraParamAreaScanBilateralTelecentricTiltDivisionLegacy.Clone();
                            hv_CameraType = "area_scan_tilt_bilateral_telecentric_division";
                        }
                        break;
                    case 12:
                        //CameraType: 'area_scan_polynomial' or 'area_scan_telecentric_polynomial'
                        if ((int)(new HTuple(((hv_CameraParam.TupleSelect(0))).TupleNotEqual(0.0))) != 0)
                        {
                            hv_ParamNames = hv_CameraParamAreaScanPolynomial.Clone();
                            hv_CameraType = "area_scan_polynomial";
                        }
                        else
                        {
                            hv_ParamNames = hv_CameraParamAreaScanTelecentricPolynomialLegacy.Clone();
                            hv_CameraType = "area_scan_telecentric_polynomial";
                        }
                        break;
                    case 14:
                        //CameraType: 'area_scan_tilt_polynomial' or 'area_scan_telecentric_tilt_polynomial'
                        if ((int)(new HTuple(((hv_CameraParam.TupleSelect(0))).TupleNotEqual(0.0))) != 0)
                        {
                            hv_ParamNames = hv_CameraParamAreaScanTiltPolynomialLegacy.Clone();
                            hv_CameraType = "area_scan_tilt_polynomial";
                        }
                        else
                        {
                            hv_ParamNames = hv_CameraParamAreaScanBilateralTelecentricTiltPolynomialLegacy.Clone();
                            hv_CameraType = "area_scan_tilt_bilateral_telecentric_polynomial";
                        }
                        break;
                    //
                    //Line Scan
                    case 11:
                        //CameraType: 'line_scan'
                        hv_ParamNames = hv_CameraParamLinesScan.Clone();
                        hv_CameraType = "line_scan";
                        break;
                    default:
                        throw new HalconException("Wrong number of values in CameraParam.");
                        break;
                }
            }
            else
            {
                //Format of camera parameters since HALCON 13
                hv_CameraType = hv_CameraParam.TupleSelect(0);
                if ((int)(new HTuple(hv_CameraType.TupleEqual("area_scan_division"))) != 0)
                {
                    if ((int)(new HTuple((new HTuple(hv_CameraParam.TupleLength())).TupleNotEqual(
                        9))) != 0)
                    {
                        throw new HalconException("Wrong number of values in CameraParam.");
                    }
                    hv_ParamNames = new HTuple();
                    hv_ParamNames[0] = "camera_type";
                    hv_ParamNames = hv_ParamNames.TupleConcat(hv_CameraParamAreaScanDivision);
                }
                else if ((int)(new HTuple(hv_CameraType.TupleEqual("area_scan_polynomial"))) != 0)
                {
                    if ((int)(new HTuple((new HTuple(hv_CameraParam.TupleLength())).TupleNotEqual(
                        13))) != 0)
                    {
                        throw new HalconException("Wrong number of values in CameraParam.");
                    }
                    hv_ParamNames = new HTuple();
                    hv_ParamNames[0] = "camera_type";
                    hv_ParamNames = hv_ParamNames.TupleConcat(hv_CameraParamAreaScanPolynomial);
                }
                else if ((int)(new HTuple(hv_CameraType.TupleEqual("area_scan_telecentric_division"))) != 0)
                {
                    if ((int)(new HTuple((new HTuple(hv_CameraParam.TupleLength())).TupleNotEqual(
                        9))) != 0)
                    {
                        throw new HalconException("Wrong number of values in CameraParam.");
                    }
                    hv_ParamNames = new HTuple();
                    hv_ParamNames[0] = "camera_type";
                    hv_ParamNames = hv_ParamNames.TupleConcat(hv_CameraParamAreaScanTelecentricDivision);
                }
                else if ((int)(new HTuple(hv_CameraType.TupleEqual("area_scan_telecentric_polynomial"))) != 0)
                {
                    if ((int)(new HTuple((new HTuple(hv_CameraParam.TupleLength())).TupleNotEqual(
                        13))) != 0)
                    {
                        throw new HalconException("Wrong number of values in CameraParam.");
                    }
                    hv_ParamNames = new HTuple();
                    hv_ParamNames[0] = "camera_type";
                    hv_ParamNames = hv_ParamNames.TupleConcat(hv_CameraParamAreaScanTelecentricPolynomial);
                }
                else if ((int)(new HTuple(hv_CameraType.TupleEqual("area_scan_tilt_division"))) != 0)
                {
                    if ((int)(new HTuple((new HTuple(hv_CameraParam.TupleLength())).TupleNotEqual(
                        12))) != 0)
                    {
                        throw new HalconException("Wrong number of values in CameraParam.");
                    }
                    hv_ParamNames = new HTuple();
                    hv_ParamNames[0] = "camera_type";
                    hv_ParamNames = hv_ParamNames.TupleConcat(hv_CameraParamAreaScanTiltDivision);
                }
                else if ((int)(new HTuple(hv_CameraType.TupleEqual("area_scan_tilt_polynomial"))) != 0)
                {
                    if ((int)(new HTuple((new HTuple(hv_CameraParam.TupleLength())).TupleNotEqual(
                        16))) != 0)
                    {
                        throw new HalconException("Wrong number of values in CameraParam.");
                    }
                    hv_ParamNames = new HTuple();
                    hv_ParamNames[0] = "camera_type";
                    hv_ParamNames = hv_ParamNames.TupleConcat(hv_CameraParamAreaScanTiltPolynomial);
                }
                else if ((int)(new HTuple(hv_CameraType.TupleEqual("area_scan_tilt_image_side_telecentric_division"))) != 0)
                {
                    if ((int)(new HTuple((new HTuple(hv_CameraParam.TupleLength())).TupleNotEqual(
                        11))) != 0)
                    {
                        throw new HalconException("Wrong number of values in CameraParam.");
                    }
                    hv_ParamNames = new HTuple();
                    hv_ParamNames[0] = "camera_type";
                    hv_ParamNames = hv_ParamNames.TupleConcat(hv_CameraParamAreaScanImageSideTelecentricTiltDivision);
                }
                else if ((int)(new HTuple(hv_CameraType.TupleEqual("area_scan_tilt_image_side_telecentric_polynomial"))) != 0)
                {
                    if ((int)(new HTuple((new HTuple(hv_CameraParam.TupleLength())).TupleNotEqual(
                        15))) != 0)
                    {
                        throw new HalconException("Wrong number of values in CameraParam.");
                    }
                    hv_ParamNames = new HTuple();
                    hv_ParamNames[0] = "camera_type";
                    hv_ParamNames = hv_ParamNames.TupleConcat(hv_CameraParamAreaScanImageSideTelecentricTiltPolynomial);
                }
                else if ((int)(new HTuple(hv_CameraType.TupleEqual("area_scan_tilt_bilateral_telecentric_division"))) != 0)
                {
                    if ((int)(new HTuple((new HTuple(hv_CameraParam.TupleLength())).TupleNotEqual(
                        11))) != 0)
                    {
                        throw new HalconException("Wrong number of values in CameraParam.");
                    }
                    hv_ParamNames = new HTuple();
                    hv_ParamNames[0] = "camera_type";
                    hv_ParamNames = hv_ParamNames.TupleConcat(hv_CameraParamAreaScanBilateralTelecentricTiltDivision);
                }
                else if ((int)(new HTuple(hv_CameraType.TupleEqual("area_scan_tilt_bilateral_telecentric_polynomial"))) != 0)
                {
                    if ((int)(new HTuple((new HTuple(hv_CameraParam.TupleLength())).TupleNotEqual(
                        15))) != 0)
                    {
                        throw new HalconException("Wrong number of values in CameraParam.");
                    }
                    hv_ParamNames = new HTuple();
                    hv_ParamNames[0] = "camera_type";
                    hv_ParamNames = hv_ParamNames.TupleConcat(hv_CameraParamAreaScanBilateralTelecentricTiltPolynomial);
                }
                else if ((int)(new HTuple(hv_CameraType.TupleEqual("area_scan_tilt_object_side_telecentric_division"))) != 0)
                {
                    if ((int)(new HTuple((new HTuple(hv_CameraParam.TupleLength())).TupleNotEqual(
                        12))) != 0)
                    {
                        throw new HalconException("Wrong number of values in CameraParam.");
                    }
                    hv_ParamNames = new HTuple();
                    hv_ParamNames[0] = "camera_type";
                    hv_ParamNames = hv_ParamNames.TupleConcat(hv_CameraParamAreaScanObjectSideTelecentricTiltDivision);
                }
                else if ((int)(new HTuple(hv_CameraType.TupleEqual("area_scan_tilt_object_side_telecentric_polynomial"))) != 0)
                {
                    if ((int)(new HTuple((new HTuple(hv_CameraParam.TupleLength())).TupleNotEqual(
                        16))) != 0)
                    {
                        throw new HalconException("Wrong number of values in CameraParam.");
                    }
                    hv_ParamNames = new HTuple();
                    hv_ParamNames[0] = "camera_type";
                    hv_ParamNames = hv_ParamNames.TupleConcat(hv_CameraParamAreaScanObjectSideTelecentricTiltPolynomial);
                }
                else if ((int)(new HTuple(hv_CameraType.TupleEqual("line_scan"))) != 0)
                {
                    if ((int)(new HTuple((new HTuple(hv_CameraParam.TupleLength())).TupleNotEqual(
                        12))) != 0)
                    {
                        throw new HalconException("Wrong number of values in CameraParam.");
                    }
                    hv_ParamNames = new HTuple();
                    hv_ParamNames[0] = "camera_type";
                    hv_ParamNames = hv_ParamNames.TupleConcat(hv_CameraParamLinesScan);
                }
                else
                {
                    throw new HalconException("Unknown camera type in CameraParam.");
                }
            }

            return;
        }

        // Chapter: Calibration / Camera Parameters
        // Short Description: Get the value of a specified camera parameter from the camera parameter tuple. 
        public void get_cam_par_data(HTuple hv_CameraParam, HTuple hv_ParamName, out HTuple hv_ParamValue)
        {



            // Local iconic variables 

            // Local control variables 

            HTuple hv_CameraType = null, hv_CameraParamNames = null;
            HTuple hv_Index = null, hv_ParamNameInd = new HTuple();
            HTuple hv_I = new HTuple();
            // Initialize local and output iconic variables 
            //get_cam_par_data returns in ParamValue the value of the
            //parameter that is given in ParamName from the tuple of
            //camera parameters that is given in CameraParam.
            //
            //Get the parameter names that correspond to the
            //elements in the input camera parameter tuple.
            get_cam_par_names(hv_CameraParam, out hv_CameraType, out hv_CameraParamNames);
            //
            //Find the index of the requested camera data and return
            //the corresponding value.
            hv_ParamValue = new HTuple();
            for (hv_Index = 0; (int)hv_Index <= (int)((new HTuple(hv_ParamName.TupleLength())) - 1); hv_Index = (int)hv_Index + 1)
            {
                hv_ParamNameInd = hv_ParamName.TupleSelect(hv_Index);
                if ((int)(new HTuple(hv_ParamNameInd.TupleEqual("camera_type"))) != 0)
                {
                    hv_ParamValue = hv_ParamValue.TupleConcat(hv_CameraType);
                    continue;
                }
                hv_I = hv_CameraParamNames.TupleFind(hv_ParamNameInd);
                if ((int)(new HTuple(hv_I.TupleNotEqual(-1))) != 0)
                {
                    hv_ParamValue = hv_ParamValue.TupleConcat(hv_CameraParam.TupleSelect(hv_I));
                }
                else
                {
                    throw new HalconException("Unknown camera parameter " + hv_ParamNameInd);
                }
            }

            return;
        }

        // Chapter: Graphics / Output
        // Short Description: Determine the optimum distance of the object to obtain a reasonable visualization 
        public void determine_optimum_pose_distance(HTuple hv_ObjectModel3DID, HTuple hv_CamParam,
            HTuple hv_ImageCoverage, HTuple hv_PoseIn, out HTuple hv_PoseOut)
        {



            // Local iconic variables 

            // Local control variables 

            HTuple hv_NumModels = null, hv_Rows = null;
            HTuple hv_Cols = null, hv_MinMinZ = null, hv_BB = null;
            HTuple hv_Seq = null, hv_DXMax = null, hv_DYMax = null;
            HTuple hv_DZMax = null, hv_Diameter = null, hv_ZAdd = null;
            HTuple hv_IBB = null, hv_BB0 = null, hv_BB1 = null, hv_BB2 = null;
            HTuple hv_BB3 = null, hv_BB4 = null, hv_BB5 = null, hv_X = null;
            HTuple hv_Y = null, hv_Z = null, hv_PoseInter = null, hv_HomMat3D = null;
            HTuple hv_QX = null, hv_QY = null, hv_QZ = null, hv_Cx = null;
            HTuple hv_Cy = null, hv_DR = null, hv_DC = null, hv_MaxDist = null;
            HTuple hv_HomMat3DRotate = new HTuple(), hv_ImageWidth = null;
            HTuple hv_ImageHeight = null, hv_MinImageSize = null, hv_Zs = null;
            HTuple hv_ZDiff = null, hv_ScaleZ = null, hv_ZNew = null;
            // Initialize local and output iconic variables 
            //Determine the optimum distance of the object to obtain
            //a reasonable visualization
            //
            hv_NumModels = new HTuple(hv_ObjectModel3DID.TupleLength());
            hv_Rows = new HTuple();
            hv_Cols = new HTuple();
            hv_MinMinZ = 1e30;
            HOperatorSet.GetObjectModel3dParams(hv_ObjectModel3DID, "bounding_box1", out hv_BB);
            //Calculate diameter over all objects to be visualized
            hv_Seq = HTuple.TupleGenSequence(0, (new HTuple(hv_BB.TupleLength())) - 1, 6);
            hv_DXMax = (((hv_BB.TupleSelect(hv_Seq + 3))).TupleMax()) - (((hv_BB.TupleSelect(
                hv_Seq))).TupleMin());
            hv_DYMax = (((hv_BB.TupleSelect(hv_Seq + 4))).TupleMax()) - (((hv_BB.TupleSelect(
                hv_Seq + 1))).TupleMin());
            hv_DZMax = (((hv_BB.TupleSelect(hv_Seq + 5))).TupleMax()) - (((hv_BB.TupleSelect(
                hv_Seq + 2))).TupleMin());
            hv_Diameter = ((((hv_DXMax * hv_DXMax) + (hv_DYMax * hv_DYMax)) + (hv_DZMax * hv_DZMax))).TupleSqrt()
                ;
            if ((int)(new HTuple(((((hv_BB.TupleAbs())).TupleSum())).TupleEqual(0.0))) != 0)
            {
                hv_BB = new HTuple();
                hv_BB = hv_BB.TupleConcat(-((new HTuple(HTuple.TupleRand(
                    3) * 1e-20)).TupleAbs()));
                hv_BB = hv_BB.TupleConcat((new HTuple(HTuple.TupleRand(
                    3) * 1e-20)).TupleAbs());
            }
            //Allow the visualization of single points or extremely small objects
            hv_ZAdd = 0.0;
            if ((int)(new HTuple(((hv_Diameter.TupleMax())).TupleLess(1e-10))) != 0)
            {
                hv_ZAdd = 0.01;
            }
            //Set extremely small diameters to 1e-10 to avoid CZ == 0.0, which would lead
            //to projection errors
            if ((int)(new HTuple(((hv_Diameter.TupleMin())).TupleLess(1e-10))) != 0)
            {
                hv_Diameter = hv_Diameter - (((((((hv_Diameter - 1e-10)).TupleSgn()) - 1)).TupleSgn()
                    ) * 1e-10);
            }
            hv_IBB = HTuple.TupleGenSequence(0, (new HTuple(hv_BB.TupleLength())) - 1, 6);
            hv_BB0 = hv_BB.TupleSelect(hv_IBB);
            hv_BB1 = hv_BB.TupleSelect(hv_IBB + 1);
            hv_BB2 = hv_BB.TupleSelect(hv_IBB + 2);
            hv_BB3 = hv_BB.TupleSelect(hv_IBB + 3);
            hv_BB4 = hv_BB.TupleSelect(hv_IBB + 4);
            hv_BB5 = hv_BB.TupleSelect(hv_IBB + 5);
            hv_X = new HTuple();
            hv_X = hv_X.TupleConcat(hv_BB0);
            hv_X = hv_X.TupleConcat(hv_BB3);
            hv_X = hv_X.TupleConcat(hv_BB0);
            hv_X = hv_X.TupleConcat(hv_BB0);
            hv_X = hv_X.TupleConcat(hv_BB3);
            hv_X = hv_X.TupleConcat(hv_BB3);
            hv_X = hv_X.TupleConcat(hv_BB0);
            hv_X = hv_X.TupleConcat(hv_BB3);
            hv_Y = new HTuple();
            hv_Y = hv_Y.TupleConcat(hv_BB1);
            hv_Y = hv_Y.TupleConcat(hv_BB1);
            hv_Y = hv_Y.TupleConcat(hv_BB4);
            hv_Y = hv_Y.TupleConcat(hv_BB1);
            hv_Y = hv_Y.TupleConcat(hv_BB4);
            hv_Y = hv_Y.TupleConcat(hv_BB1);
            hv_Y = hv_Y.TupleConcat(hv_BB4);
            hv_Y = hv_Y.TupleConcat(hv_BB4);
            hv_Z = new HTuple();
            hv_Z = hv_Z.TupleConcat(hv_BB2);
            hv_Z = hv_Z.TupleConcat(hv_BB2);
            hv_Z = hv_Z.TupleConcat(hv_BB2);
            hv_Z = hv_Z.TupleConcat(hv_BB5);
            hv_Z = hv_Z.TupleConcat(hv_BB2);
            hv_Z = hv_Z.TupleConcat(hv_BB5);
            hv_Z = hv_Z.TupleConcat(hv_BB5);
            hv_Z = hv_Z.TupleConcat(hv_BB5);
            hv_PoseInter = hv_PoseIn.TupleReplace(2, (-(hv_Z.TupleMin())) + (2 * (hv_Diameter.TupleMax()
                )));
            HOperatorSet.PoseToHomMat3d(hv_PoseInter, out hv_HomMat3D);
            //Determine the maximum extension of the projection
            HOperatorSet.AffineTransPoint3d(hv_HomMat3D, hv_X, hv_Y, hv_Z, out hv_QX, out hv_QY,
                out hv_QZ);
            HOperatorSet.Project3dPoint(hv_QX, hv_QY, hv_QZ, hv_CamParam, out hv_Rows, out hv_Cols);
            hv_MinMinZ = hv_QZ.TupleMin();
            get_cam_par_data(hv_CamParam, "cx", out hv_Cx);
            get_cam_par_data(hv_CamParam, "cy", out hv_Cy);
            hv_DR = hv_Rows - hv_Cy;
            hv_DC = hv_Cols - hv_Cx;
            hv_DR = (hv_DR.TupleMax()) - (hv_DR.TupleMin());
            hv_DC = (hv_DC.TupleMax()) - (hv_DC.TupleMin());
            hv_MaxDist = (((hv_DR * hv_DR) + (hv_DC * hv_DC))).TupleSqrt();
            //
            if ((int)(new HTuple(hv_MaxDist.TupleLess(1e-10))) != 0)
            {
                //If the object has no extension in the above projection (looking along
                //a line), we determine the extension of the object in a rotated view
                HOperatorSet.HomMat3dRotateLocal(hv_HomMat3D, (new HTuple(90)).TupleRad(),
                    "x", out hv_HomMat3DRotate);
                HOperatorSet.AffineTransPoint3d(hv_HomMat3DRotate, hv_X, hv_Y, hv_Z, out hv_QX,
                    out hv_QY, out hv_QZ);
                HOperatorSet.Project3dPoint(hv_QX, hv_QY, hv_QZ, hv_CamParam, out hv_Rows,
                    out hv_Cols);
                hv_DR = hv_Rows - hv_Cy;
                hv_DC = hv_Cols - hv_Cx;
                hv_DR = (hv_DR.TupleMax()) - (hv_DR.TupleMin());
                hv_DC = (hv_DC.TupleMax()) - (hv_DC.TupleMin());
                hv_MaxDist = ((hv_MaxDist.TupleConcat((((hv_DR * hv_DR) + (hv_DC * hv_DC))).TupleSqrt()
                    ))).TupleMax();
            }
            //
            get_cam_par_data(hv_CamParam, "image_width", out hv_ImageWidth);
            get_cam_par_data(hv_CamParam, "image_height", out hv_ImageHeight);
            hv_MinImageSize = ((hv_ImageWidth.TupleConcat(hv_ImageHeight))).TupleMin();
            //
            hv_Z = hv_PoseInter.TupleSelect(2);
            hv_Zs = hv_MinMinZ.Clone();
            hv_ZDiff = hv_Z - hv_Zs;
            hv_ScaleZ = hv_MaxDist / (((0.5 * hv_MinImageSize) * hv_ImageCoverage) * 2.0);
            hv_ZNew = ((hv_ScaleZ * hv_Zs) + hv_ZDiff) + hv_ZAdd;
            hv_PoseOut = hv_PoseInter.TupleReplace(2, hv_ZNew);
            //

            return;
        }



        // Chapter: Graphics / Output
        // Short Description: Can replace disp_object_model_3d if there is no OpenGL available. 
        public void disp_object_model_no_opengl(out HObject ho_ModelContours, HTuple hv_ObjectModel3DID,
            HTuple hv_GenParamName, HTuple hv_GenParamValue, HTuple hv_WindowHandleBuffer,
            HTuple hv_CamParam, HTuple hv_PosesOut)
        {



            // Local iconic variables 

            // Local control variables 

            HTuple hv_Idx = null, hv_CustomParamName = new HTuple();
            HTuple hv_CustomParamValue = new HTuple(), hv_Font = null;
            HTuple hv_IndicesDispBackGround = null, hv_Indices = new HTuple();
            HTuple hv_ImageWidth = null, hv_HasPolygons = null, hv_HasTri = null;
            HTuple hv_HasPoints = null, hv_HasLines = null, hv_NumPoints = null;
            HTuple hv_IsPrimitive = null, hv_Center = null, hv_Diameter = null;
            HTuple hv_OpenGlHiddenSurface = null, hv_CenterX = null;
            HTuple hv_CenterY = null, hv_CenterZ = null, hv_PosObjectsZ = null;
            HTuple hv_I = new HTuple(), hv_Pose = new HTuple(), hv_HomMat3DObj = new HTuple();
            HTuple hv_PosObjCenterX = new HTuple(), hv_PosObjCenterY = new HTuple();
            HTuple hv_PosObjCenterZ = new HTuple(), hv_PosObjectsX = new HTuple();
            HTuple hv_PosObjectsY = new HTuple(), hv_Color = null;
            HTuple hv_Indices1 = new HTuple(), hv_Indices2 = new HTuple();
            HTuple hv_J = null, hv_Indices3 = new HTuple(), hv_HomMat3D = new HTuple();
            HTuple hv_SampledObjectModel3D = new HTuple(), hv_X = new HTuple();
            HTuple hv_Y = new HTuple(), hv_Z = new HTuple(), hv_HomMat3D1 = new HTuple();
            HTuple hv_Qx = new HTuple(), hv_Qy = new HTuple(), hv_Qz = new HTuple();
            HTuple hv_Row = new HTuple(), hv_Column = new HTuple();
            HTuple hv_ObjectModel3DConvexHull = new HTuple(), hv_Exception = new HTuple();
            // Initialize local and output iconic variables 
            HOperatorSet.GenEmptyObj(out ho_ModelContours);
            //This procedure allows to use project_object_model_3d to simulate a disp_object_model_3d
            //call for small objects. Large objects are sampled down to display.
            hv_Idx = hv_GenParamName.TupleFind("point_size");
            if ((int)((new HTuple(hv_Idx.TupleLength())).TupleAnd(new HTuple(hv_Idx.TupleNotEqual(
                -1)))) != 0)
            {
                hv_CustomParamName = "point_size";
                hv_CustomParamValue = hv_GenParamValue.TupleSelect(hv_Idx);
                if ((int)(new HTuple(hv_CustomParamValue.TupleEqual(1))) != 0)
                {
                    hv_CustomParamValue = 0;
                }
            }
            else
            {
                hv_CustomParamName = new HTuple();
                hv_CustomParamValue = new HTuple();
            }
            HOperatorSet.GetFont(hv_ExpDefaultWinHandle, out hv_Font);
            HOperatorSet.TupleFind(hv_GenParamName, "disp_background", out hv_IndicesDispBackGround);
            if ((int)(new HTuple(hv_IndicesDispBackGround.TupleNotEqual(-1))) != 0)
            {
                HOperatorSet.TupleFind(hv_GenParamName.TupleSelect(hv_IndicesDispBackGround),
                    "false", out hv_Indices);
                if ((int)(new HTuple(hv_Indices.TupleNotEqual(-1))) != 0)
                {
                    HOperatorSet.ClearWindow(hv_ExpDefaultWinHandle);
                }
            }
            //set_display_font(hv_ExpDefaultWinHandle, 11, "mono", "false", "false");//字体
            get_cam_par_data(hv_CamParam, "image_width", out hv_ImageWidth);
            disp_message(hv_ExpDefaultWinHandle, "OpenGL missing!", "image", 5, hv_ImageWidth - 130,
                "red", "false");
            HOperatorSet.SetFont(hv_ExpDefaultWinHandle, hv_Font);
            HOperatorSet.GetObjectModel3dParams(hv_ObjectModel3DID, "has_polygons", out hv_HasPolygons);
            HOperatorSet.GetObjectModel3dParams(hv_ObjectModel3DID, "has_triangles", out hv_HasTri);
            HOperatorSet.GetObjectModel3dParams(hv_ObjectModel3DID, "has_points", out hv_HasPoints);
            HOperatorSet.GetObjectModel3dParams(hv_ObjectModel3DID, "has_lines", out hv_HasLines);
            HOperatorSet.GetObjectModel3dParams(hv_ObjectModel3DID, "num_points", out hv_NumPoints);
            HOperatorSet.GetObjectModel3dParams(hv_ObjectModel3DID, "has_primitive_data",
                out hv_IsPrimitive);
            HOperatorSet.GetObjectModel3dParams(hv_ObjectModel3DID, "center", out hv_Center);
            HOperatorSet.GetObjectModel3dParams(hv_ObjectModel3DID, "diameter", out hv_Diameter);
            HOperatorSet.GetSystem("opengl_hidden_surface_removal_enable", out hv_OpenGlHiddenSurface);
            HOperatorSet.SetSystem("opengl_hidden_surface_removal_enable", "false");
            //Sort the objects by inverse z
            hv_CenterX = hv_Center.TupleSelect(HTuple.TupleGenSequence(0, (new HTuple(hv_Center.TupleLength()
                )) - 1, 3));
            hv_CenterY = hv_Center.TupleSelect(HTuple.TupleGenSequence(0, (new HTuple(hv_Center.TupleLength()
                )) - 1, 3) + 1);
            hv_CenterZ = hv_Center.TupleSelect(HTuple.TupleGenSequence(0, (new HTuple(hv_Center.TupleLength()
                )) - 1, 3) + 2);
            hv_PosObjectsZ = new HTuple();
            if ((int)(new HTuple((new HTuple(hv_PosesOut.TupleLength())).TupleGreater(7))) != 0)
            {
                for (hv_I = 0; (int)hv_I <= (int)((new HTuple(hv_ObjectModel3DID.TupleLength())) - 1); hv_I = (int)hv_I + 1)
                {
                    hv_Pose = hv_PosesOut.TupleSelectRange(hv_I * 7, (hv_I * 7) + 6);
                    HOperatorSet.PoseToHomMat3d(hv_Pose, out hv_HomMat3DObj);
                    HOperatorSet.AffineTransPoint3d(hv_HomMat3DObj, hv_CenterX.TupleSelect(hv_I),
                        hv_CenterY.TupleSelect(hv_I), hv_CenterZ.TupleSelect(hv_I), out hv_PosObjCenterX,
                        out hv_PosObjCenterY, out hv_PosObjCenterZ);
                    hv_PosObjectsZ = hv_PosObjectsZ.TupleConcat(hv_PosObjCenterZ);
                }
            }
            else
            {
                hv_Pose = hv_PosesOut.TupleSelectRange(0, 6);
                HOperatorSet.PoseToHomMat3d(hv_Pose, out hv_HomMat3DObj);
                HOperatorSet.AffineTransPoint3d(hv_HomMat3DObj, hv_CenterX, hv_CenterY, hv_CenterZ,
                    out hv_PosObjectsX, out hv_PosObjectsY, out hv_PosObjectsZ);
            }
            hv_Idx = ((hv_PosObjectsZ.TupleSortIndex())).TupleInverse();
            hv_Color = "white";
            HOperatorSet.SetColor(hv_ExpDefaultWinHandle, hv_Color);
            if ((int)(new HTuple((new HTuple(hv_GenParamName.TupleLength())).TupleGreater(
                0))) != 0)
            {
                HOperatorSet.TupleFind(hv_GenParamName, "colored", out hv_Indices1);
                HOperatorSet.TupleFind(hv_GenParamName, "color", out hv_Indices2);
                if ((int)(new HTuple(((hv_Indices1.TupleSelect(0))).TupleNotEqual(-1))) != 0)
                {
                    if ((int)(new HTuple(((hv_GenParamValue.TupleSelect(hv_Indices1.TupleSelect(
                        0)))).TupleEqual(3))) != 0)
                    {
                        hv_Color = new HTuple();
                        hv_Color[0] = "red";
                        hv_Color[1] = "green";
                        hv_Color[2] = "blue";
                    }
                    else if ((int)(new HTuple(((hv_GenParamValue.TupleSelect(hv_Indices1.TupleSelect(
                        0)))).TupleEqual(6))) != 0)
                    {
                        hv_Color = new HTuple();
                        hv_Color[0] = "red";
                        hv_Color[1] = "green";
                        hv_Color[2] = "blue";
                        hv_Color[3] = "cyan";
                        hv_Color[4] = "magenta";
                        hv_Color[5] = "yellow";
                    }
                    else if ((int)(new HTuple(((hv_GenParamValue.TupleSelect(hv_Indices1.TupleSelect(
                        0)))).TupleEqual(12))) != 0)
                    {
                        hv_Color = new HTuple();
                        hv_Color[0] = "red";
                        hv_Color[1] = "green";
                        hv_Color[2] = "blue";
                        hv_Color[3] = "cyan";
                        hv_Color[4] = "magenta";
                        hv_Color[5] = "yellow";
                        hv_Color[6] = "coral";
                        hv_Color[7] = "slate blue";
                        hv_Color[8] = "spring green";
                        hv_Color[9] = "orange red";
                        hv_Color[10] = "pink";
                        hv_Color[11] = "gold";
                    }
                }
                else if ((int)(new HTuple(((hv_Indices2.TupleSelect(0))).TupleNotEqual(
                    -1))) != 0)
                {
                    hv_Color = hv_GenParamValue.TupleSelect(hv_Indices2.TupleSelect(0));
                }
            }
            for (hv_J = 0; (int)hv_J <= (int)((new HTuple(hv_ObjectModel3DID.TupleLength())) - 1); hv_J = (int)hv_J + 1)
            {
                hv_I = hv_Idx.TupleSelect(hv_J);
                if ((int)((new HTuple((new HTuple((new HTuple(((hv_HasPolygons.TupleSelect(
                    hv_I))).TupleEqual("true"))).TupleOr(new HTuple(((hv_HasTri.TupleSelect(
                    hv_I))).TupleEqual("true"))))).TupleOr(new HTuple(((hv_HasPoints.TupleSelect(
                    hv_I))).TupleEqual("true"))))).TupleOr(new HTuple(((hv_HasLines.TupleSelect(
                    hv_I))).TupleEqual("true")))) != 0)
                {
                    if ((int)(new HTuple((new HTuple(hv_GenParamName.TupleLength())).TupleGreater(
                        0))) != 0)
                    {
                        HOperatorSet.TupleFind(hv_GenParamName, "color_" + hv_I, out hv_Indices3);
                        if ((int)(new HTuple(((hv_Indices3.TupleSelect(0))).TupleNotEqual(-1))) != 0)
                        {
                            HOperatorSet.SetColor(hv_ExpDefaultWinHandle, hv_GenParamValue.TupleSelect(
                                hv_Indices3.TupleSelect(0)));
                        }
                        else
                        {
                            HOperatorSet.SetColor(hv_ExpDefaultWinHandle, hv_Color.TupleSelect(hv_I % (new HTuple(hv_Color.TupleLength()
                                ))));
                        }
                    }
                    if ((int)(new HTuple((new HTuple(hv_PosesOut.TupleLength())).TupleGreaterEqual(
                        (hv_I * 7) + 6))) != 0)
                    {
                        hv_Pose = hv_PosesOut.TupleSelectRange(hv_I * 7, (hv_I * 7) + 6);
                    }
                    else
                    {
                        hv_Pose = hv_PosesOut.TupleSelectRange(0, 6);
                    }
                    if ((int)(new HTuple(((hv_NumPoints.TupleSelect(hv_I))).TupleLess(10000))) != 0)
                    {
                        ho_ModelContours.Dispose();
                        HOperatorSet.ProjectObjectModel3d(out ho_ModelContours, hv_ObjectModel3DID.TupleSelect(
                            hv_I), hv_CamParam, hv_Pose, hv_CustomParamName, hv_CustomParamValue);
                        HOperatorSet.DispObj(ho_ModelContours, hv_ExpDefaultWinHandle);
                    }
                    else
                    {
                        HOperatorSet.PoseToHomMat3d(hv_Pose, out hv_HomMat3D);
                        HOperatorSet.SampleObjectModel3d(hv_ObjectModel3DID.TupleSelect(hv_I),
                            "fast", 0.01 * (hv_Diameter.TupleSelect(hv_I)), new HTuple(), new HTuple(),
                            out hv_SampledObjectModel3D);
                        ho_ModelContours.Dispose();
                        HOperatorSet.ProjectObjectModel3d(out ho_ModelContours, hv_SampledObjectModel3D,
                            hv_CamParam, hv_Pose, "point_size", 1);
                        HOperatorSet.GetObjectModel3dParams(hv_SampledObjectModel3D, "point_coord_x",
                            out hv_X);
                        HOperatorSet.GetObjectModel3dParams(hv_SampledObjectModel3D, "point_coord_y",
                            out hv_Y);
                        HOperatorSet.GetObjectModel3dParams(hv_SampledObjectModel3D, "point_coord_z",
                            out hv_Z);
                        HOperatorSet.PoseToHomMat3d(hv_Pose, out hv_HomMat3D1);
                        HOperatorSet.AffineTransPoint3d(hv_HomMat3D1, hv_X, hv_Y, hv_Z, out hv_Qx,
                            out hv_Qy, out hv_Qz);
                        HOperatorSet.Project3dPoint(hv_Qx, hv_Qy, hv_Qz, hv_CamParam, out hv_Row,
                            out hv_Column);
                        HOperatorSet.DispObj(ho_ModelContours, hv_ExpDefaultWinHandle);
                        HOperatorSet.ClearObjectModel3d(hv_SampledObjectModel3D);
                    }
                }
                else
                {
                    if ((int)(new HTuple((new HTuple(hv_GenParamName.TupleLength())).TupleGreater(
                        0))) != 0)
                    {
                        HOperatorSet.TupleFind(hv_GenParamName, "color_" + hv_I, out hv_Indices3);
                        if ((int)(new HTuple(((hv_Indices3.TupleSelect(0))).TupleNotEqual(-1))) != 0)
                        {
                            HOperatorSet.SetColor(hv_ExpDefaultWinHandle, hv_GenParamValue.TupleSelect(
                                hv_Indices3.TupleSelect(0)));
                        }
                        else
                        {
                            HOperatorSet.SetColor(hv_ExpDefaultWinHandle, hv_Color.TupleSelect(hv_I % (new HTuple(hv_Color.TupleLength()
                                ))));
                        }
                    }
                    if ((int)(new HTuple((new HTuple(hv_PosesOut.TupleLength())).TupleGreaterEqual(
                        (hv_I * 7) + 6))) != 0)
                    {
                        hv_Pose = hv_PosesOut.TupleSelectRange(hv_I * 7, (hv_I * 7) + 6);
                    }
                    else
                    {
                        hv_Pose = hv_PosesOut.TupleSelectRange(0, 6);
                    }
                    if ((int)(new HTuple(((hv_IsPrimitive.TupleSelect(hv_I))).TupleEqual("true"))) != 0)
                    {
                        try
                        {
                            HOperatorSet.ConvexHullObjectModel3d(hv_ObjectModel3DID.TupleSelect(hv_I),
                                out hv_ObjectModel3DConvexHull);
                            if ((int)(new HTuple(((hv_NumPoints.TupleSelect(hv_I))).TupleLess(10000))) != 0)
                            {
                                ho_ModelContours.Dispose();
                                HOperatorSet.ProjectObjectModel3d(out ho_ModelContours, hv_ObjectModel3DConvexHull,
                                    hv_CamParam, hv_Pose, hv_CustomParamName, hv_CustomParamValue);
                                HOperatorSet.DispObj(ho_ModelContours, hv_ExpDefaultWinHandle);
                            }
                            else
                            {
                                HOperatorSet.PoseToHomMat3d(hv_Pose, out hv_HomMat3D);
                                HOperatorSet.SampleObjectModel3d(hv_ObjectModel3DConvexHull, "fast",
                                    0.01 * (hv_Diameter.TupleSelect(hv_I)), new HTuple(), new HTuple(),
                                    out hv_SampledObjectModel3D);
                                ho_ModelContours.Dispose();
                                HOperatorSet.ProjectObjectModel3d(out ho_ModelContours, hv_SampledObjectModel3D,
                                    hv_CamParam, hv_Pose, "point_size", 1);
                                HOperatorSet.DispObj(ho_ModelContours, hv_ExpDefaultWinHandle);
                                HOperatorSet.ClearObjectModel3d(hv_SampledObjectModel3D);
                            }
                            HOperatorSet.ClearObjectModel3d(hv_ObjectModel3DConvexHull);
                        }
                        // catch (Exception) 
                        catch (HalconException HDevExpDefaultException1)
                        {
                            HDevExpDefaultException1.ToHTuple(out hv_Exception);
                        }
                    }
                }
            }
            HOperatorSet.SetSystem("opengl_hidden_surface_removal_enable", hv_OpenGlHiddenSurface);

            return;
        }



        // Chapter: Graphics / Output
        // Short Description: Reflect the pose change that was introduced by the user by moving the mouse 
        public void analyze_graph_event(HObject ho_BackgroundImage, HTuple hv_MouseMapping,
            HTuple hv_Button, HTuple hv_Row, HTuple hv_Column, HTuple hv_WindowHandle, HTuple hv_WindowHandleBuffer,
            HTuple hv_VirtualTrackball, HTuple hv_TrackballSize, HTuple hv_SelectedObjectIn,
            HTuple hv_Scene3D, HTuple hv_AlphaOrig, HTuple hv_ObjectModel3DID, HTuple hv_CamParam,
            HTuple hv_GenParamName,
            HTuple hv_GenParamValue, HTuple hv_PosesIn, HTuple hv_ButtonHoldIn, HTuple hv_TBCenter,
            HTuple hv_WindowCenteredRotationlIn, 
            out HTuple hv_PosesOut, out HTuple hv_SelectedObjectOut, out HTuple hv_ButtonHoldOut,
            out HTuple hv_WindowCenteredRotationOut)
        {




            // Local iconic variables 

            HObject ho_ImageDump = null;

            // Local control variables 

    
            HTuple hv_InvLog2 = null, hv_Seconds = new HTuple();
            HTuple hv_ModelIndex = new HTuple(), hv_Exception1 = new HTuple();
            HTuple hv_HomMat3DIdentity = new HTuple(), hv_NumModels = new HTuple();
            HTuple hv_Width = new HTuple(), hv_Height = new HTuple();
            HTuple hv_MinImageSize = new HTuple(), hv_TrackballRadiusPixel = new HTuple();
            HTuple hv_TrackballCenterRow = new HTuple(), hv_TrackballCenterCol = new HTuple();
            HTuple hv_NumChannels = new HTuple(), hv_ColorImage = new HTuple();
            HTuple hv_BAnd = new HTuple(), hv_SensFactor = new HTuple();
            HTuple hv_IsButtonTrans = new HTuple(), hv_IsButtonRot = new HTuple();
            HTuple hv_IsButtonDist = new HTuple(), hv_MRow1 = new HTuple();
            HTuple hv_MCol1 = new HTuple(), hv_ButtonLoop = new HTuple();
            HTuple hv_MRow2 = new HTuple(), hv_MCol2 = new HTuple();
            HTuple hv_PX = new HTuple(), hv_PY = new HTuple(), hv_PZ = new HTuple();
            HTuple hv_QX1 = new HTuple(), hv_QY1 = new HTuple(), hv_QZ1 = new HTuple();
            HTuple hv_QX2 = new HTuple(), hv_QY2 = new HTuple(), hv_QZ2 = new HTuple();
            HTuple hv_Len = new HTuple(), hv_Dist = new HTuple(), hv_Translate = new HTuple();
            HTuple hv_Index = new HTuple(), hv_PoseIn = new HTuple();
            HTuple hv_HomMat3DIn = new HTuple(), hv_HomMat3DOut = new HTuple();
            HTuple hv_PoseOut = new HTuple(), hv_Indices = new HTuple();
            HTuple hv_Sequence = new HTuple(), hv_Mod = new HTuple();
            HTuple hv_SequenceReal = new HTuple(), hv_Sequence2Int = new HTuple();
            HTuple hv_Selected = new HTuple(), hv_InvSelected = new HTuple();
            HTuple hv_Exception = new HTuple(), hv_DRow = new HTuple();
            HTuple hv_TranslateZ = new HTuple(), hv_MX1 = new HTuple();
            HTuple hv_MY1 = new HTuple(), hv_MX2 = new HTuple(), hv_MY2 = new HTuple();
            HTuple hv_RelQuaternion = new HTuple(), hv_HomMat3DRotRel = new HTuple();
            HTuple hv_HomMat3DInTmp1 = new HTuple(), hv_HomMat3DInTmp = new HTuple();
            HTuple hv_PosesOut2 = new HTuple();
            HTuple hv_Column_COPY_INP_TMP = hv_Column.Clone();
            HTuple hv_PosesIn_COPY_INP_TMP = hv_PosesIn.Clone();
            HTuple hv_Row_COPY_INP_TMP = hv_Row.Clone();
            HTuple hv_TBCenter_COPY_INP_TMP = hv_TBCenter.Clone();
            HTuple hv_TBSize_COPY_INP_TMP ;

            // 初始化本地和输出图标变量
            HOperatorSet.GenEmptyObj(out ho_ImageDump);
            try
            {
                //This procedure reflects
                //- the pose change that was introduced by the user by
                //  moving the mouse
                //- the selection of a single object
                //
                //global tuple gIsSinglePose
                //
                hv_ButtonHoldOut = hv_ButtonHoldIn.Clone();
                hv_PosesOut = hv_PosesIn_COPY_INP_TMP.Clone();
                hv_SelectedObjectOut = hv_SelectedObjectIn.Clone();
                hv_WindowCenteredRotationOut = hv_WindowCenteredRotationlIn.Clone();
                hv_InvLog2 = 1.0 / ((new HTuple(2)).TupleLog());

                // Ctrl（16）+ Alt（32）+鼠标左键（1）=>切换旋转中心位置
                if (hv_Button == (int)49)    //hv_MouseMapping.TupleSelect(6)
                {
                    #region
                    if ((int)(hv_ButtonHoldOut) != 0)
                    {
                        ho_ImageDump.Dispose();

                        return;
                    }
                    //Ctrl (16) + Alt (32) + left mouse button (1) => Toggle rotation center position
                    //If WindowCenteredRotation is not 1, set it to 1, otherwise, set it to 2
                    HOperatorSet.CountSeconds(out hv_Seconds); //时间
                    if (hv_WindowCenteredRotationOut == 1)
                    {
                        hv_WindowCenteredRotationOut = 2;
                    }
                    else
                    {
                        hv_WindowCenteredRotationOut = 1;
                    }
                    hv_ButtonHoldOut = 1;
                    ho_ImageDump.Dispose();

                    return;
                    #endregion
                }
                //右键选择点云
                if (hv_Button == (int)4&&hv_ObjectModel3DID.TupleLength()<(int)1000)
                {
                    #region
                    if ((int)(hv_ButtonHoldOut) != 0)
                    {
                        ho_ImageDump.Dispose();

                        return;
                    }
                    //Ctrl (16) + left mouse button (1) => Select an object
                    try
                    {
                        HOperatorSet.SetScene3dParam(hv_Scene3D, "object_index_persistence", "true");
                        HOperatorSet.DisplayScene3d(hv_ExpDefaultWinHandle, hv_Scene3D, 0);
                        HOperatorSet.GetDisplayScene3dInfo(hv_ExpDefaultWinHandle, hv_Scene3D,
                            hv_Row_COPY_INP_TMP, hv_Column_COPY_INP_TMP, "object_index", out hv_ModelIndex);
                        HOperatorSet.SetScene3dParam(hv_Scene3D, "object_index_persistence", "false");
                    }
                    // catch (Exception1) 
                    catch (HalconException HDevExpDefaultException1)
                    {
                        HDevExpDefaultException1.ToHTuple(out hv_Exception1);
                        //* NO OpenGL, no selection possible
                        ho_ImageDump.Dispose();

                        return;
                    }
                    if ((int)(new HTuple(hv_ModelIndex.TupleEqual(-1))) != 0)
                    {
                        //Background click:
                        if ((int)(new HTuple(((hv_SelectedObjectOut.TupleSum())).TupleEqual(new HTuple(hv_SelectedObjectOut.TupleLength()
                            )))) != 0)
                        {
                            //If all objects are already selected, deselect all
                            hv_SelectedObjectOut = HTuple.TupleGenConst(new HTuple(hv_ObjectModel3DID.TupleLength()
                                ), 0);
                        }
                        else
                        {
                            //Otherwise select all
                            hv_SelectedObjectOut = HTuple.TupleGenConst(new HTuple(hv_ObjectModel3DID.TupleLength()
                                ), 1);
                        }
                    }
                    else
                    {
                        //Object click:
                        if (hv_SelectedObjectOut == null)
                            hv_SelectedObjectOut = new HTuple();
                        hv_SelectedObjectOut[hv_ModelIndex] = ((hv_SelectedObjectOut.TupleSelect(
                            hv_ModelIndex))).TupleNot();
                    }
                    hv_ButtonHoldOut = 1;
                    #endregion
                }
                else
                {
                    //生成变换矩阵
                    HOperatorSet.HomMat3dIdentity(out hv_HomMat3DIdentity);
                    hv_NumModels = new HTuple(hv_ObjectModel3DID.TupleLength());  //模型数量
                    get_cam_par_data(hv_CamParam, "image_width", out hv_Width);   //宽度
                    get_cam_par_data(hv_CamParam, "image_height", out hv_Height); //高度
                    hv_MinImageSize = ((hv_Width.TupleConcat(hv_Height))).TupleMin();
                    hv_TrackballRadiusPixel = (hv_TrackballSize * hv_MinImageSize) / 2.0;
                    //将轨迹球固定在窗口中央
                    hv_TrackballCenterRow = hv_Height / 2;
                    hv_TrackballCenterCol = hv_Width / 2;

                    //模型数量小于1000
                    if ( hv_ObjectModel3DID.TupleLength()< hv_MaxNumModels)
                    {
                        if (hv_WindowCenteredRotationOut=1)
                        {
                            get_trackball_center_fixed(hv_SelectedObjectIn, hv_TrackballCenterRow,
                                hv_TrackballCenterCol, hv_TrackballRadiusPixel, hv_Scene3D, hv_ObjectModel3DID,
                                hv_PosesIn_COPY_INP_TMP, hv_WindowHandleBuffer, hv_CamParam, hv_GenParamName,
                                hv_GenParamValue, out hv_TBCenter_COPY_INP_TMP, out hv_TBSize_COPY_INP_TMP);
                        }
                        else
                        {
                            get_trackball_center(hv_SelectedObjectIn, hv_TrackballRadiusPixel, hv_ObjectModel3DID,
                                hv_PosesIn_COPY_INP_TMP, out hv_TBCenter_COPY_INP_TMP, out hv_TBSize_COPY_INP_TMP);
                        }
                    }
                    //0：没有按钮，//1：左键，//2：中键，//4：右键，//8：Shift键，//16：Ctrl键，//32：ALT键。
                    //Alt (32) => 灵敏度较低
                    HOperatorSet.TupleRsh(hv_Button, 5, out hv_BAnd);//将元组按位向右移动
                    if ((int)(hv_BAnd % 6) != 0)
                    {
                        hv_SensFactor = 0.1;
                    }
                    else
                    {
                        hv_SensFactor = 1.0;
                    }
                    //平移点云 shift left
                    hv_IsButtonTrans = new HTuple(hv_Button == 17);
                    
                    //旋转 
                    hv_IsButtonRot = new HTuple(hv_Button == 1 || hv_Button == 33);
                    //高度变化
                    hv_IsButtonDist = new HTuple(hv_Button == 2 || hv_Button == 34 || hv_Button == 5 || hv_Button == 37 || hv_Button == 9 || hv_Button == 41);

                    if (hv_IsButtonTrans != 0)
                    {
                        #region 点云平移
                        //Translate in XY-direction
                        hv_MRow1 = hv_Row_COPY_INP_TMP.Clone();
                        hv_MCol1 = hv_Column_COPY_INP_TMP.Clone();
                        while ((int)(hv_IsButtonTrans) != 0)
                        {
                            try
                            {
                                HOperatorSet.GetMpositionSubPix(hv_ExpDefaultWinHandle, out hv_Row_COPY_INP_TMP,
                                    out hv_Column_COPY_INP_TMP, out hv_ButtonLoop);
                                hv_IsButtonTrans = new HTuple(hv_ButtonLoop.TupleEqual(hv_Button));
                                hv_MRow2 = hv_MRow1 + ((hv_Row_COPY_INP_TMP - hv_MRow1) * hv_SensFactor);
                                hv_MCol2 = hv_MCol1 + ((hv_Column_COPY_INP_TMP - hv_MCol1) * hv_SensFactor);
                                HOperatorSet.GetLineOfSight(hv_MRow1, hv_MCol1, hv_CamParam, out hv_PX,
                                    out hv_PY, out hv_PZ, out hv_QX1, out hv_QY1, out hv_QZ1);
                                HOperatorSet.GetLineOfSight(hv_MRow2, hv_MCol2, hv_CamParam, out hv_PX,
                                    out hv_PY, out hv_PZ, out hv_QX2, out hv_QY2, out hv_QZ2);
                                hv_Len = ((((hv_QX1 * hv_QX1) + (hv_QY1 * hv_QY1)) + (hv_QZ1 * hv_QZ1))).TupleSqrt()
                                    ;
                                hv_Dist = (((((hv_TBCenter_COPY_INP_TMP.TupleSelect(0)) * (hv_TBCenter_COPY_INP_TMP.TupleSelect(
                                    0))) + ((hv_TBCenter_COPY_INP_TMP.TupleSelect(1)) * (hv_TBCenter_COPY_INP_TMP.TupleSelect(
                                    1)))) + ((hv_TBCenter_COPY_INP_TMP.TupleSelect(2)) * (hv_TBCenter_COPY_INP_TMP.TupleSelect(
                                    2))))).TupleSqrt();
                                hv_Translate = ((((((hv_QX2 - hv_QX1)).TupleConcat(hv_QY2 - hv_QY1))).TupleConcat(
                                    hv_QZ2 - hv_QZ1)) * hv_Dist) / hv_Len;
                                hv_PosesOut = new HTuple();
                                if ((int)(new HTuple(hv_NumModels.TupleLessEqual(hv_MaxNumModels))) != 0)
                                {
                                    HTuple end_val110 = hv_NumModels - 1;
                                    HTuple step_val110 = 1;
                                    for (hv_Index = 0; hv_Index.Continue(end_val110, step_val110); hv_Index = hv_Index.TupleAdd(step_val110))
                                    {
                                        hv_PoseIn = hv_PosesIn_COPY_INP_TMP.TupleSelectRange(hv_Index * 7,
                                            (hv_Index * 7) + 6);
                                        if ((int)(hv_SelectedObjectOut.TupleSelect(hv_Index)) != 0)
                                        {
                                            HOperatorSet.PoseToHomMat3d(hv_PoseIn, out hv_HomMat3DIn);
                                            HOperatorSet.HomMat3dTranslate(hv_HomMat3DIn, hv_Translate.TupleSelect(
                                                0), hv_Translate.TupleSelect(1), hv_Translate.TupleSelect(
                                                2), out hv_HomMat3DOut);
                                            HOperatorSet.HomMat3dToPose(hv_HomMat3DOut, out hv_PoseOut);
                                            HOperatorSet.SetScene3dInstancePose(hv_Scene3D, hv_Index, hv_PoseOut);
                                        }
                                        else
                                        {
                                            hv_PoseOut = hv_PoseIn.Clone();
                                        }
                                        hv_PosesOut = hv_PosesOut.TupleConcat(hv_PoseOut);
                                    }
                                }
                                else
                                {
                                    HOperatorSet.TupleFind(hv_SelectedObjectOut, 1, out hv_Indices);
                                    hv_PoseIn = hv_PosesIn_COPY_INP_TMP.TupleSelectRange((hv_Indices.TupleSelect(
                                        0)) * 7, ((hv_Indices.TupleSelect(0)) * 7) + 6);
                                    HOperatorSet.PoseToHomMat3d(hv_PoseIn, out hv_HomMat3DIn);
                                    HOperatorSet.HomMat3dTranslate(hv_HomMat3DIn, hv_Translate.TupleSelect(
                                        0), hv_Translate.TupleSelect(1), hv_Translate.TupleSelect(2),
                                        out hv_HomMat3DOut);
                                    HOperatorSet.HomMat3dToPose(hv_HomMat3DOut, out hv_PoseOut);
                                    hv_Sequence = HTuple.TupleGenSequence(0, (hv_NumModels * 7) - 1, 1);
                                    HOperatorSet.TupleMod(hv_Sequence, 7, out hv_Mod);
                                    hv_SequenceReal = HTuple.TupleGenSequence(0, hv_NumModels - (1.0 / 7.0),
                                        1.0 / 7.0);
                                    hv_Sequence2Int = hv_SequenceReal.TupleInt();
                                    HOperatorSet.TupleSelect(hv_SelectedObjectOut, hv_Sequence2Int, out hv_Selected);
                                    hv_InvSelected = 1 - hv_Selected;
                                    HOperatorSet.TupleSelect(hv_PoseOut, hv_Mod, out hv_PosesOut);
                                    hv_PosesOut = (hv_PosesOut * hv_Selected) + (hv_PosesIn_COPY_INP_TMP * hv_InvSelected);
                                    HOperatorSet.SetScene3dInstancePose(hv_Scene3D, HTuple.TupleGenSequence(
                                        0, hv_NumModels - 1, 1), hv_PosesOut);
                                }
                                dump_image_output(ho_BackgroundImage, hv_ExpDefaultWinHandle, hv_Scene3D,
                                    hv_AlphaOrig, hv_ObjectModel3DID, hv_GenParamName, hv_GenParamValue,
                                    hv_CamParam, hv_PosesOut,  
                                     hv_SelectedObjectOut);
                                ho_ImageDump.Dispose();
                                HOperatorSet.DumpWindowImage(out ho_ImageDump, hv_ExpDefaultWinHandle);
                                //dev_set_window(...);
                                HOperatorSet.DispObj(ho_ImageDump, hv_ExpDefaultWinHandle);
                                //
                                hv_MRow1 = hv_Row_COPY_INP_TMP.Clone();
                                hv_MCol1 = hv_Column_COPY_INP_TMP.Clone();
                                hv_PosesIn_COPY_INP_TMP = hv_PosesOut.Clone();
                            }
                            // catch (Exception) 
                            catch (HalconException HDevExpDefaultException1)
                            {
                                HDevExpDefaultException1.ToHTuple(out hv_Exception);
                                //Keep waiting
                            }
                        }
                        #endregion
                    }
                    else if ((int)(hv_IsButtonDist) != 0)
                    {
                        #region 改变高度
                        //Change the Z distance
                        hv_MRow1 = hv_Row_COPY_INP_TMP.Clone();
                        while ((int)(hv_IsButtonDist) != 0)
                        {
                            try
                            {
                                HOperatorSet.GetMpositionSubPix(hv_ExpDefaultWinHandle, out hv_Row_COPY_INP_TMP,
                                    out hv_Column_COPY_INP_TMP, out hv_ButtonLoop);
                                hv_IsButtonDist = new HTuple(hv_ButtonLoop.TupleEqual(hv_Button));
                                hv_MRow2 = hv_Row_COPY_INP_TMP.Clone();
                                hv_DRow = hv_MRow2 - hv_MRow1;
                                hv_Dist = (((((hv_TBCenter_COPY_INP_TMP.TupleSelect(0)) * (hv_TBCenter_COPY_INP_TMP.TupleSelect(
                                    0))) + ((hv_TBCenter_COPY_INP_TMP.TupleSelect(1)) * (hv_TBCenter_COPY_INP_TMP.TupleSelect(
                                    1)))) + ((hv_TBCenter_COPY_INP_TMP.TupleSelect(2)) * (hv_TBCenter_COPY_INP_TMP.TupleSelect(
                                    2))))).TupleSqrt();
                                hv_TranslateZ = (((-hv_Dist) * hv_DRow) * 0.003) * hv_SensFactor;
                                if (hv_TBCenter_COPY_INP_TMP == null)
                                    hv_TBCenter_COPY_INP_TMP = new HTuple();
                                hv_TBCenter_COPY_INP_TMP[2] = (hv_TBCenter_COPY_INP_TMP.TupleSelect(
                                    2)) + hv_TranslateZ;
                                hv_PosesOut = new HTuple();
                                if ((int)(new HTuple(hv_NumModels.TupleLessEqual(hv_MaxNumModels))) != 0)
                                {
                                    HTuple end_val164 = hv_NumModels - 1;
                                    HTuple step_val164 = 1;
                                    for (hv_Index = 0; hv_Index.Continue(end_val164, step_val164); hv_Index = hv_Index.TupleAdd(step_val164))
                                    {
                                        hv_PoseIn = hv_PosesIn_COPY_INP_TMP.TupleSelectRange(hv_Index * 7,
                                            (hv_Index * 7) + 6);
                                        if ((int)(hv_SelectedObjectOut.TupleSelect(hv_Index)) != 0)
                                        {
                                            //Transform the whole scene or selected object only
                                            HOperatorSet.PoseToHomMat3d(hv_PoseIn, out hv_HomMat3DIn);
                                            HOperatorSet.HomMat3dTranslate(hv_HomMat3DIn, 0, 0, hv_TranslateZ,
                                                out hv_HomMat3DOut);
                                            HOperatorSet.HomMat3dToPose(hv_HomMat3DOut, out hv_PoseOut);
                                            HOperatorSet.SetScene3dInstancePose(hv_Scene3D, hv_Index, hv_PoseOut);
                                        }
                                        else
                                        {
                                            hv_PoseOut = hv_PoseIn.Clone();
                                        }
                                        hv_PosesOut = hv_PosesOut.TupleConcat(hv_PoseOut);
                                    }
                                }
                                else
                                {
                                    HOperatorSet.TupleFind(hv_SelectedObjectOut, 1, out hv_Indices);
                                    hv_PoseIn = hv_PosesIn_COPY_INP_TMP.TupleSelectRange((hv_Indices.TupleSelect(
                                        0)) * 7, ((hv_Indices.TupleSelect(0)) * 7) + 6);
                                    HOperatorSet.PoseToHomMat3d(hv_PoseIn, out hv_HomMat3DIn);
                                    HOperatorSet.HomMat3dTranslate(hv_HomMat3DIn, 0, 0, hv_TranslateZ,
                                        out hv_HomMat3DOut);
                                    HOperatorSet.HomMat3dToPose(hv_HomMat3DOut, out hv_PoseOut);
                                    hv_Sequence = HTuple.TupleGenSequence(0, (hv_NumModels * 7) - 1, 1);
                                    HOperatorSet.TupleMod(hv_Sequence, 7, out hv_Mod);
                                    hv_SequenceReal = HTuple.TupleGenSequence(0, hv_NumModels - (1.0 / 7.0),
                                        1.0 / 7.0);
                                    hv_Sequence2Int = hv_SequenceReal.TupleInt();
                                    HOperatorSet.TupleSelect(hv_SelectedObjectOut, hv_Sequence2Int, out hv_Selected);
                                    hv_InvSelected = 1 - hv_Selected;
                                    HOperatorSet.TupleSelect(hv_PoseOut, hv_Mod, out hv_PosesOut);
                                    hv_PosesOut = (hv_PosesOut * hv_Selected) + (hv_PosesIn_COPY_INP_TMP * hv_InvSelected);
                                    HOperatorSet.SetScene3dInstancePose(hv_Scene3D, HTuple.TupleGenSequence(
                                        0, hv_NumModels - 1, 1), hv_PosesOut);
                                }
                                dump_image_output(ho_BackgroundImage, hv_ExpDefaultWinHandle, hv_Scene3D,
                                    hv_AlphaOrig, hv_ObjectModel3DID, hv_GenParamName, hv_GenParamValue,
                                    hv_CamParam, hv_PosesOut,
                                    hv_SelectedObjectOut);
                                ho_ImageDump.Dispose();
                                HOperatorSet.DumpWindowImage(out ho_ImageDump, hv_ExpDefaultWinHandle);
                                //dev_set_window(...);
                                HOperatorSet.DispObj(ho_ImageDump, hv_ExpDefaultWinHandle);
                                //
                                hv_MRow1 = hv_Row_COPY_INP_TMP.Clone();
                                hv_PosesIn_COPY_INP_TMP = hv_PosesOut.Clone();
                            }
                            // catch (Exception) 
                            catch (HalconException HDevExpDefaultException1)
                            {
                                HDevExpDefaultException1.ToHTuple(out hv_Exception);
                                //Keep waiting
                            }
                        }
                        #endregion 
                    }
                    else if ((int)(hv_IsButtonRot) != 0)
                    {
                        #region 旋转
                        //Rotate the object
                        hv_MRow1 = hv_Row_COPY_INP_TMP.Clone();
                        hv_MCol1 = hv_Column_COPY_INP_TMP.Clone();
                        while ((int)(hv_IsButtonRot) != 0)
                        {
                            try
                            {
                                HOperatorSet.GetMpositionSubPix(hv_ExpDefaultWinHandle, out hv_Row_COPY_INP_TMP,
                                    out hv_Column_COPY_INP_TMP, out hv_ButtonLoop);
                                hv_IsButtonRot = new HTuple(hv_ButtonLoop.TupleEqual(hv_Button));
                                hv_MRow2 = hv_Row_COPY_INP_TMP.Clone();
                                hv_MCol2 = hv_Column_COPY_INP_TMP.Clone();
                                //Transform the pixel coordinates to relative image coordinates
                                hv_MX1 = (hv_TrackballCenterCol - hv_MCol1) / (0.5 * hv_MinImageSize);
                                hv_MY1 = (hv_TrackballCenterRow - hv_MRow1) / (0.5 * hv_MinImageSize);
                                hv_MX2 = (hv_TrackballCenterCol - hv_MCol2) / (0.5 * hv_MinImageSize);
                                hv_MY2 = (hv_TrackballCenterRow - hv_MRow2) / (0.5 * hv_MinImageSize);
                                //Compute the quaternion rotation that corresponds to the mouse
                                //movement
                                trackball(hv_MX1, hv_MY1, hv_MX2, hv_MY2, hv_VirtualTrackball, hv_TrackballSize,
                                    hv_SensFactor, out hv_RelQuaternion);
                                //Transform the quaternion to a rotation matrix
                                HOperatorSet.QuatToHomMat3d(hv_RelQuaternion, out hv_HomMat3DRotRel);
                                hv_PosesOut = new HTuple();
                                if ((int)(new HTuple(hv_NumModels.TupleLessEqual(hv_MaxNumModels))) != 0)
                                {
                                    HTuple end_val226 = hv_NumModels - 1;
                                    HTuple step_val226 = 1;
                                    for (hv_Index = 0; hv_Index.Continue(end_val226, step_val226); hv_Index = hv_Index.TupleAdd(step_val226))
                                    {
                                        hv_PoseIn = hv_PosesIn_COPY_INP_TMP.TupleSelectRange(hv_Index * 7,
                                            (hv_Index * 7) + 6);
                                        if ((int)(hv_SelectedObjectOut.TupleSelect(hv_Index)) != 0)
                                        {
                                            //Transform the whole scene or selected object only
                                            HOperatorSet.PoseToHomMat3d(hv_PoseIn, out hv_HomMat3DIn);
                                            HOperatorSet.HomMat3dTranslate(hv_HomMat3DIn, -(hv_TBCenter_COPY_INP_TMP.TupleSelect(
                                                0)), -(hv_TBCenter_COPY_INP_TMP.TupleSelect(1)), -(hv_TBCenter_COPY_INP_TMP.TupleSelect(
                                                2)), out hv_HomMat3DIn);
                                            HOperatorSet.HomMat3dCompose(hv_HomMat3DRotRel, hv_HomMat3DIn,
                                                out hv_HomMat3DIn);
                                            HOperatorSet.HomMat3dTranslate(hv_HomMat3DIn, hv_TBCenter_COPY_INP_TMP.TupleSelect(
                                                0), hv_TBCenter_COPY_INP_TMP.TupleSelect(1), hv_TBCenter_COPY_INP_TMP.TupleSelect(
                                                2), out hv_HomMat3DOut);
                                            HOperatorSet.HomMat3dToPose(hv_HomMat3DOut, out hv_PoseOut);
                                            HOperatorSet.SetScene3dInstancePose(hv_Scene3D, hv_Index, hv_PoseOut);
                                        }
                                        else
                                        {
                                            hv_PoseOut = hv_PoseIn.Clone();
                                        }
                                        hv_PosesOut = hv_PosesOut.TupleConcat(hv_PoseOut);
                                    }
                                }
                                else
                                {
                                    HOperatorSet.TupleFind(hv_SelectedObjectOut, 1, out hv_Indices);
                                    hv_PoseIn = hv_PosesIn_COPY_INP_TMP.TupleSelectRange((hv_Indices.TupleSelect(
                                        0)) * 7, ((hv_Indices.TupleSelect(0)) * 7) + 6);
                                    HOperatorSet.PoseToHomMat3d(hv_PoseIn, out hv_HomMat3DIn);
                                    HOperatorSet.HomMat3dTranslate(hv_HomMat3DIn, -(hv_TBCenter_COPY_INP_TMP.TupleSelect(
                                        0)), -(hv_TBCenter_COPY_INP_TMP.TupleSelect(1)), -(hv_TBCenter_COPY_INP_TMP.TupleSelect(
                                        2)), out hv_HomMat3DInTmp1);
                                    HOperatorSet.HomMat3dCompose(hv_HomMat3DRotRel, hv_HomMat3DInTmp1,
                                        out hv_HomMat3DInTmp);
                                    HOperatorSet.HomMat3dTranslate(hv_HomMat3DInTmp, hv_TBCenter_COPY_INP_TMP.TupleSelect(
                                        0), hv_TBCenter_COPY_INP_TMP.TupleSelect(1), hv_TBCenter_COPY_INP_TMP.TupleSelect(
                                        2), out hv_HomMat3DOut);
                                    HOperatorSet.HomMat3dToPose(hv_HomMat3DOut, out hv_PoseOut);
                                    hv_Sequence = HTuple.TupleGenSequence(0, (hv_NumModels * 7) - 1, 1);
                                    HOperatorSet.TupleMod(hv_Sequence, 7, out hv_Mod);
                                    hv_SequenceReal = HTuple.TupleGenSequence(0, hv_NumModels - (1.0 / 7.0),
                                        1.0 / 7.0);
                                    hv_Sequence2Int = hv_SequenceReal.TupleInt();
                                    HOperatorSet.TupleSelect(hv_SelectedObjectOut, hv_Sequence2Int, out hv_Selected);
                                    hv_InvSelected = 1 - hv_Selected;
                                    HOperatorSet.TupleSelect(hv_PoseOut, hv_Mod, out hv_PosesOut);
                                    hv_PosesOut2 = (hv_PosesOut * hv_Selected) + (hv_PosesIn_COPY_INP_TMP * hv_InvSelected);
                                    hv_PosesOut = hv_PosesOut2.Clone();
                                    HOperatorSet.SetScene3dInstancePose(hv_Scene3D, HTuple.TupleGenSequence(
                                        0, hv_NumModels - 1, 1), hv_PosesOut);
                                }
                                dump_image_output(ho_BackgroundImage, hv_ExpDefaultWinHandle, hv_Scene3D,
                                    hv_AlphaOrig, hv_ObjectModel3DID, hv_GenParamName, hv_GenParamValue,
                                    hv_CamParam, hv_PosesOut,
                                     hv_SelectedObjectOut);
                                ho_ImageDump.Dispose();
                                HOperatorSet.DumpWindowImage(out ho_ImageDump, hv_ExpDefaultWinHandle);
                                //dev_set_window(...);
                                HOperatorSet.DispObj(ho_ImageDump, hv_ExpDefaultWinHandle);
                                //
                                hv_MRow1 = hv_Row_COPY_INP_TMP.Clone();
                                hv_MCol1 = hv_Column_COPY_INP_TMP.Clone();
                                hv_PosesIn_COPY_INP_TMP = hv_PosesOut.Clone();
                            }
                            // catch (Exception) 
                            catch (HalconException HDevExpDefaultException1)
                            {
                                HDevExpDefaultException1.ToHTuple(out hv_Exception);
                                //Keep waiting
                            }
                        }
                        #endregion
                    }
                    hv_PosesOut = hv_PosesIn_COPY_INP_TMP.Clone();
                }
                ho_ImageDump.Dispose();

                return;
            }
            catch (HalconException HDevExpDefaultException)
            {
                ho_ImageDump.Dispose();

                throw HDevExpDefaultException;
            }
        }



        //public void max_line_width(HTuple hv_WindowHandle, HTuple hv_Lines, out HTuple hv_MaxWidth)
        //{



        //    // Local iconic variables 

        //    // Local control variables 

        //    HTuple hv_Index = null, hv_Ascent = new HTuple();
        //    HTuple hv_Descent = new HTuple(), hv_LineWidth = new HTuple();
        //    HTuple hv_LineHeight = new HTuple();
        //    // Initialize local and output iconic variables 
        //    hv_MaxWidth = 0;
        //    for (hv_Index = 0; (int)hv_Index <= (int)((new HTuple(hv_Lines.TupleLength())) - 1); hv_Index = (int)hv_Index + 1)
        //    {
        //        HOperatorSet.GetStringExtents(hv_ExpDefaultWinHandle, hv_Lines.TupleSelect(
        //            hv_Index), out hv_Ascent, out hv_Descent, out hv_LineWidth, out hv_LineHeight);
        //        hv_MaxWidth = ((hv_LineWidth.TupleConcat(hv_MaxWidth))).TupleMax();
        //    }

        //    return;
        //}



        // Chapter: Graphics / Output
        // Short Description: Project an image point onto the trackball 


        public void project_point_on_trackball(HTuple hv_X, HTuple hv_Y, HTuple hv_VirtualTrackball,
            HTuple hv_TrackballSize, out HTuple hv_V)
        {



            // Local iconic variables 

            // Local control variables 

            HTuple hv_R = new HTuple(), hv_XP = new HTuple();
            HTuple hv_YP = new HTuple(), hv_ZP = new HTuple();
            // Initialize local and output iconic variables 
            if ((int)(new HTuple(hv_VirtualTrackball.TupleEqual("shoemake"))) != 0)
            {
                //Virtual Trackball according to Shoemake
                hv_R = (((hv_X * hv_X) + (hv_Y * hv_Y))).TupleSqrt();
                if ((int)(new HTuple(hv_R.TupleLessEqual(hv_TrackballSize))) != 0)
                {
                    hv_XP = hv_X.Clone();
                    hv_YP = hv_Y.Clone();
                    hv_ZP = (((hv_TrackballSize * hv_TrackballSize) - (hv_R * hv_R))).TupleSqrt();
                }
                else
                {
                    hv_XP = (hv_X * hv_TrackballSize) / hv_R;
                    hv_YP = (hv_Y * hv_TrackballSize) / hv_R;
                    hv_ZP = 0;
                }
            }
            else
            {
                //Virtual Trackball according to Bell
                hv_R = (((hv_X * hv_X) + (hv_Y * hv_Y))).TupleSqrt();
                if ((int)(new HTuple(hv_R.TupleLessEqual(hv_TrackballSize * 0.70710678))) != 0)
                {
                    hv_XP = hv_X.Clone();
                    hv_YP = hv_Y.Clone();
                    hv_ZP = (((hv_TrackballSize * hv_TrackballSize) - (hv_R * hv_R))).TupleSqrt();
                }
                else
                {
                    hv_XP = hv_X.Clone();
                    hv_YP = hv_Y.Clone();
                    hv_ZP = ((0.6 * hv_TrackballSize) * hv_TrackballSize) / hv_R;
                }
            }
            hv_V = new HTuple();
            hv_V = hv_V.TupleConcat(hv_XP);
            hv_V = hv_V.TupleConcat(hv_YP);
            hv_V = hv_V.TupleConcat(hv_ZP);

            return;
        }

        // Chapter: Graphics / Output
        // Short Description: Compute the 3D rotation from the mouse movement 
        public void trackball(HTuple hv_MX1, HTuple hv_MY1, HTuple hv_MX2, HTuple hv_MY2,
            HTuple hv_VirtualTrackball, HTuple hv_TrackballSize, HTuple hv_SensFactor, out HTuple hv_QuatRotation)
        {



            // Local iconic variables 

            // Local control variables 

            HTuple hv_P1 = null, hv_P2 = null, hv_RotAxis = null;
            HTuple hv_D = null, hv_T = null, hv_RotAngle = null, hv_Len = null;
            // Initialize local and output iconic variables 
            hv_QuatRotation = new HTuple();
            //Compute the 3D rotation from the mouse movement
            //
            if ((int)((new HTuple(hv_MX1.TupleEqual(hv_MX2))).TupleAnd(new HTuple(hv_MY1.TupleEqual(
                hv_MY2)))) != 0)
            {
                hv_QuatRotation = new HTuple();
                hv_QuatRotation[0] = 1;
                hv_QuatRotation[1] = 0;
                hv_QuatRotation[2] = 0;
                hv_QuatRotation[3] = 0;

                return;
            }
            //Project the image point onto the trackball
            project_point_on_trackball(hv_MX1, hv_MY1, hv_VirtualTrackball, hv_TrackballSize,
                out hv_P1);
            project_point_on_trackball(hv_MX2, hv_MY2, hv_VirtualTrackball, hv_TrackballSize,
                out hv_P2);
            //The cross product of the projected points defines the rotation axis
            tuple_vector_cross_product(hv_P1, hv_P2, out hv_RotAxis);
            //Compute the rotation angle
            hv_D = hv_P2 - hv_P1;
            hv_T = (((((hv_D * hv_D)).TupleSum())).TupleSqrt()) / (2.0 * hv_TrackballSize);
            if ((int)(new HTuple(hv_T.TupleGreater(1.0))) != 0)
            {
                hv_T = 1.0;
            }
            if ((int)(new HTuple(hv_T.TupleLess(-1.0))) != 0)
            {
                hv_T = -1.0;
            }
            hv_RotAngle = (2.0 * (hv_T.TupleAsin())) * hv_SensFactor;
            hv_Len = ((((hv_RotAxis * hv_RotAxis)).TupleSum())).TupleSqrt();
            if ((int)(new HTuple(hv_Len.TupleGreater(0.0))) != 0)
            {
                hv_RotAxis = hv_RotAxis / hv_Len;
            }
            HOperatorSet.AxisAngleToQuat(hv_RotAxis.TupleSelect(0), hv_RotAxis.TupleSelect(
                1), hv_RotAxis.TupleSelect(2), hv_RotAngle, out hv_QuatRotation);

            return;
        }

        // Chapter: Tuple / Arithmetic
        // Short Description: Calculates the cross product of two vectors of length 3. 
        public void tuple_vector_cross_product(HTuple hv_V1, HTuple hv_V2, out HTuple hv_VC)
        {



            // Local iconic variables 
            // Initialize local and output iconic variables 
            //The caller must ensure that the length of both input vectors is 3
            hv_VC = ((hv_V1.TupleSelect(1)) * (hv_V2.TupleSelect(2))) - ((hv_V1.TupleSelect(2)) * (hv_V2.TupleSelect(
                1)));
            hv_VC = hv_VC.TupleConcat(((hv_V1.TupleSelect(2)) * (hv_V2.TupleSelect(0))) - ((hv_V1.TupleSelect(
                0)) * (hv_V2.TupleSelect(2))));
            hv_VC = hv_VC.TupleConcat(((hv_V1.TupleSelect(0)) * (hv_V2.TupleSelect(1))) - ((hv_V1.TupleSelect(
                1)) * (hv_V2.TupleSelect(0))));

            return;
        }


        //显示
        public void visualize_object_model_3d(HTuple hv_WindowHandle, HTuple hv_ObjectModel3D,
            HTuple hv_CamParam, HTuple hv_PoseIn, HTuple hv_GenParamName, HTuple hv_GenParamValue,
            out HTuple hv_PoseOut)
        {
            HObject ho_Image = null;
            HTuple hv_Scene3DTest = null;
            HTuple hv_Scene3D = null, hv_WindowHandleBuffer = new HTuple();
            HTuple hv_NumModels = null, hv_SelectedObject = null, hv_ClipRegion = null;
            HTuple hv_RowNotUsed = new HTuple();
            HTuple hv_ColumnNotUsed = new HTuple(), hv_Width = new HTuple();
            HTuple hv_Height = new HTuple(), hv_WPRow1 = new HTuple();
            HTuple hv_WPColumn1 = new HTuple(), hv_WPRow2 = new HTuple();
            HTuple hv_WPColumn2 = new HTuple(), hv_CamParamValue = new HTuple();
            HTuple hv_Center = new HTuple(), hv_Poses = new HTuple();
            HTuple hv_Sequence = new HTuple();
            HTuple hv_PoseEstimated = new HTuple();
            HTuple hv_Exception = new HTuple(), hv_OpenGLInfo = new HTuple();
            HTuple hv_NumChannels = new HTuple();
            HTuple hv_CameraIndex = new HTuple(), hv_AllInstances = new HTuple();
            HTuple hv_AlphaOrig = new HTuple();
            HTuple hv_I = new HTuple(), hv_ParamName = new HTuple();
            HTuple hv_ParamValue = new HTuple(), hv_ParamNameTrunk = new HTuple();
            HTuple hv_Instance = new HTuple();
            HTuple hv_TBCenter = new HTuple();
            HTuple hv_ButtonHold = new HTuple();
            HTuple hv_GraphEvent = new HTuple();
            HTuple hv_GraphButtonRow = new HTuple();
            HTuple hv_GraphButtonColumn = new HTuple(), hv_GraphButton = new HTuple();
            HTuple hv_e = new HTuple();
            HTuple hv_CamParam_COPY_INP_TMP = hv_CamParam.Clone();
            HTuple hv_GenParamName_COPY_INP_TMP = hv_GenParamName.Clone();
            HTuple hv_GenParamValue_COPY_INP_TMP = hv_GenParamValue.Clone();
            HTuple hv_PoseIn_COPY_INP_TMP = hv_PoseIn.Clone();


            HOperatorSet.GenEmptyObj(out ho_Image);
            hv_PoseOut = new HTuple();
            try
            {
                hv_Scene3DTest = new HTuple();
                hv_Scene3D = new HTuple();
                hv_WindowHandleBuffer = new HTuple();
                hv_NumModels = new HTuple(hv_ObjectModel3D.TupleLength());
                hv_SelectedObject = HTuple.TupleGenConst(hv_ObjectModel3D.TupleLength(), 1);
                HOperatorSet.GetSystem("clip_region", out hv_ClipRegion);
                HOperatorSet.SetSystem("clip_region", "false");
                try
                {
                    hv_ExpDefaultWinHandle = hv_WindowHandle;
                    HOperatorSet.GetWindowExtents(hv_ExpDefaultWinHandle, out hv_RowNotUsed,
                        out hv_ColumnNotUsed, out hv_Width, out hv_Height);
                    HOperatorSet.GetPart(hv_ExpDefaultWinHandle, out hv_WPRow1, out hv_WPColumn1,
                        out hv_WPRow2, out hv_WPColumn2);
                    HOperatorSet.SetPart(hv_ExpDefaultWinHandle, 0, 0, hv_Height - 1, hv_Width - 1);
                    gen_cam_par_area_scan_division(0.06, 0, 8.5e-6, 8.5e-6, hv_Width / 2, hv_Height / 2,
                        hv_Width, hv_Height, out hv_CamParam_COPY_INP_TMP);
                 
                    //计算3d模型中心
                    get_object_models_center(hv_ObjectModel3D, out hv_Center);
                    //生成姿态
                    HOperatorSet.CreatePose(-(hv_Center.TupleSelect(0)), -(hv_Center.TupleSelect(
                        1)), -(hv_Center.TupleSelect(2)), 0, 0, 0, "Rp+T", "gba", "point",
                        out hv_PoseIn_COPY_INP_TMP);
                    determine_optimum_pose_distance(hv_ObjectModel3D, hv_CamParam_COPY_INP_TMP,
                        0.9, hv_PoseIn_COPY_INP_TMP, out hv_PoseEstimated);
                    hv_Poses = new HTuple();
                    hv_Sequence = HTuple.TupleGenSequence(0, (hv_NumModels * 7) - 1, 1);
                    hv_Poses = hv_PoseEstimated.TupleSelect(hv_Sequence % 7);

                    HOperatorSet.SetPart(hv_ExpDefaultWinHandle, 0, 0, hv_Height - 1, hv_Width - 1);
                    //检测opengl是否可用
                    gUsesOpenGL = "true";
                    HOperatorSet.GetSystem("opengl_info", out hv_OpenGLInfo);
                    if (hv_OpenGLInfo == "No OpenGL support included.")
                    {
                        gUsesOpenGL = "false";
                    }
                    else
                    {
                        #region Opengl 不可用
                        //HOperatorSet.GenObjectModel3dFromPoints(0, 0, 0, out hv_DummyObjectModel3D);
                        //HOperatorSet.CreateScene3d(out hv_Scene3DTest);
                        //HOperatorSet.AddScene3dCamera(hv_Scene3DTest, hv_CamParam_COPY_INP_TMP,
                        //    out hv_CameraIndexTest);
                        //determine_optimum_pose_distance(hv_DummyObjectModel3D, hv_CamParam_COPY_INP_TMP,
                        //    0.9, ((((((new HTuple(0)).TupleConcat(0)).TupleConcat(0)).TupleConcat(
                        //    0)).TupleConcat(0)).TupleConcat(0)).TupleConcat(0), out hv_PoseTest);
                        //HOperatorSet.AddScene3dInstance(hv_Scene3DTest, hv_DummyObjectModel3D,
                        //    hv_PoseTest, out hv_InstanceIndexTest);
                        //try
                        //{
                        //    HOperatorSet.DisplayScene3d(hv_ExpDefaultWinHandle, hv_Scene3DTest,
                        //        hv_InstanceIndexTest);
                        //}
                        //catch (HalconException HDevExpDefaultException2)
                        //{
                        //    HDevExpDefaultException2.ToHTuple(out hv_Exception);
                        //    gUsesOpenGL = "false";                              
                        //}
                        //HOperatorSet.ClearScene3d(hv_Scene3DTest);
                        //hv_Scene3DTest = new HTuple();
                        //HOperatorSet.ClearObjectModel3d(hv_DummyObjectModel3D);
                        #endregion
                    }
                    //清空窗口
                    HOperatorSet.ClearWindow(hv_ExpDefaultWinHandle);
                    //背景图片
                    ho_Image.Dispose();
                    HOperatorSet.DumpWindowImage(out ho_Image, hv_ExpDefaultWinHandle);
                    HOperatorSet.CountChannels(ho_Image, out hv_NumChannels);
                    //生成3d显示模型
                    HOperatorSet.CreateScene3d(out hv_Scene3D);
                    HOperatorSet.AddScene3dCamera(hv_Scene3D, hv_CamParam_COPY_INP_TMP, out hv_CameraIndex);
                    HOperatorSet.AddScene3dInstance(hv_Scene3D, hv_ObjectModel3D, hv_Poses, out hv_AllInstances);
                    HOperatorSet.SetScene3dParam(hv_Scene3D, "disp_background", "true");
                    hv_AlphaOrig = HTuple.TupleGenConst(hv_NumModels, 1);
                    for (hv_I = 0; hv_I < hv_GenParamName_COPY_INP_TMP.TupleLength(); hv_I++)
                    {
                        hv_ParamName = hv_GenParamName_COPY_INP_TMP.TupleSelect(hv_I);
                        hv_ParamValue = hv_GenParamValue_COPY_INP_TMP.TupleSelect(hv_I);
                        try
                        {
                            HOperatorSet.SetScene3dParam(hv_Scene3D, hv_ParamName, hv_ParamValue);
                            continue;
                        }
                        #region  参数设置异常
                        catch (HalconException HDevExpDefaultException2)
                        {
                            HDevExpDefaultException2.ToHTuple(out hv_Exception);
                            if ((int)((new HTuple(((hv_Exception.TupleSelect(0))).TupleEqual(1203))).TupleOr(
                                new HTuple(((hv_Exception.TupleSelect(0))).TupleEqual(1303)))) != 0)
                            {
                                throw new HalconException((("Wrong type or value for parameter " + hv_ParamName) + ": ") + hv_ParamValue);
                            }
                        }
                        hv_ParamNameTrunk = hv_ParamName.TupleRegexpReplace("_\\d+$", "");
                        if ((int)(new HTuple(hv_ParamName.TupleEqual(hv_ParamNameTrunk))) != 0)
                        {
                            hv_Instance = HTuple.TupleGenSequence(0, hv_NumModels - 1, 1);
                        }
                        else
                        {
                            hv_Instance = ((hv_ParamName.TupleRegexpReplace(("^" + hv_ParamNameTrunk) + "_(\\d+)$",
                                "$1"))).TupleNumber();
                            if ((int)((new HTuple(hv_Instance.TupleLess(0))).TupleOr(new HTuple(hv_Instance.TupleGreater(
                                hv_NumModels - 1)))) != 0)
                            {
                                throw new HalconException(("Parameter " + hv_ParamName) + " refers to a non existing 3D object model");
                            }
                        }
                        try
                        {
                            HOperatorSet.SetScene3dInstanceParam(hv_Scene3D, hv_Instance, hv_ParamNameTrunk,
                                hv_ParamValue);
                        }
                        // catch (Exception) 
                        catch (HalconException HDevExpDefaultException2)
                        {
                            HDevExpDefaultException2.ToHTuple(out hv_Exception);
                            if ((int)((new HTuple(((hv_Exception.TupleSelect(0))).TupleEqual(1204))).TupleOr(
                                new HTuple(((hv_Exception.TupleSelect(0))).TupleEqual(1304)))) != 0)
                            {
                                throw new HalconException((("Wrong type or value for parameter " + hv_ParamName) + ": ") + hv_ParamValue);
                            }
                            else if ((int)((new HTuple(((hv_Exception.TupleSelect(0))).TupleEqual(
                                1203))).TupleOr(new HTuple(((hv_Exception.TupleSelect(0))).TupleEqual(
                                1303)))) != 0)
                            {
                                throw new HalconException("Wrong parameter name " + hv_ParamName);
                            }
                            else
                            {
                                throw new HalconException(hv_Exception);
                            }
                        }
                        if ((int)(new HTuple(hv_ParamNameTrunk.TupleEqual("alpha"))) != 0)
                        {
                            if (hv_AlphaOrig == null)
                                hv_AlphaOrig = new HTuple();
                            hv_AlphaOrig[hv_Instance] = hv_ParamValue;
                        }
                        #endregion
                    }               
                    hv_ButtonHold = 0;
                    ///////////////////////////////////////////////////显示模型////////////////////////////////////////////
                    //在缓冲区窗口中渲染3D对象模型。
                    dump_image_output(ho_Image, hv_ExpDefaultWinHandle, hv_Scene3D, hv_AlphaOrig,
                        hv_ObjectModel3D, hv_GenParamName_COPY_INP_TMP, hv_GenParamValue_COPY_INP_TMP,
                        hv_CamParam_COPY_INP_TMP, hv_Poses, hv_SelectedObject);

                    while (!bBreak)
                    {
                        #region
                        //dump_window_image 保存窗口内的图片
                        hv_GraphEvent = 0;
                        //监控鼠标状态
                        while (!bBreak)
                        {
                            try
                            {
                                Thread.Sleep(8);

                                //获取鼠标 Row Colum button
                                HOperatorSet.GetMpositionSubPix(hv_ExpDefaultWinHandle, out hv_GraphButtonRow,
                                    out hv_GraphButtonColumn, out hv_GraphButton);

                                if (hv_GraphButton != 0)
                                {
                                    hv_GraphEvent = 1;
                                    break;
                                }
                                else
                                {
                                    hv_ButtonHold = 0;
                                }
                            }
                            catch (HalconException HDevExpDefaultException2)
                            {
                                HDevExpDefaultException2.ToHTuple(out hv_Exception);
                            }
                        }
                        //计算鼠标拖动姿态
                        if ((int)(hv_GraphEvent) != 0)
                        {

                            analyze_graph_event(ho_Image, hv_MouseMapping, hv_GraphButton, hv_GraphButtonRow,
                                hv_GraphButtonColumn, hv_WindowHandle, hv_WindowHandleBuffer, "shoemake",
                                hv_TrackballSize, hv_SelectedObject, hv_Scene3D, hv_AlphaOrig, hv_ObjectModel3D,
                                hv_CamParam_COPY_INP_TMP, 
                                hv_GenParamName_COPY_INP_TMP, hv_GenParamValue_COPY_INP_TMP, hv_Poses,
                                hv_ButtonHold, hv_TBCenter, hv_WindowCenteredRotation,
                                out hv_Poses, out hv_SelectedObject, out hv_ButtonHold,
                                out hv_WindowCenteredRotation);
                        }
                        #endregion
                    }
                    hv_PoseOut = hv_Poses.Clone();

                    HOperatorSet.SetSystem("clip_region", hv_ClipRegion);
                    HOperatorSet.SetPart(hv_ExpDefaultWinHandle, hv_WPRow1, hv_WPColumn1, hv_WPRow2,
                        hv_WPColumn2);
                    HOperatorSet.ClearScene3d(hv_Scene3D);
                    hv_Scene3D = new HTuple();
                }
                catch (HalconException HDevExpDefaultException1)
                {
                    #region  捕获异常
                    HDevExpDefaultException1.ToHTuple(out hv_Exception);
                    try
                    {
                        if ((int)(new HTuple((new HTuple(0)).TupleLess(new HTuple(hv_Scene3DTest.TupleLength()
                            )))) != 0)
                        {
                            HOperatorSet.ClearScene3d(hv_Scene3DTest);
                            hv_Scene3DTest = new HTuple();
                        }
                        if ((int)(new HTuple((new HTuple(0)).TupleLess(new HTuple(hv_Scene3D.TupleLength()
                            )))) != 0)
                        {
                            HOperatorSet.ClearScene3d(hv_Scene3D);
                            hv_Scene3D = new HTuple();
                        }
                        if ((int)(new HTuple((new HTuple(0)).TupleLess(new HTuple(hv_WindowHandleBuffer.TupleLength()
                            )))) != 0)
                        {
                            hv_WindowHandleBuffer = new HTuple();
                        }

                    }
                    catch (HalconException HDevExpDefaultException2)
                    {
                        HDevExpDefaultException2.ToHTuple(out hv_e);
                    }

                    throw new HalconException(hv_Exception);
                    #endregion
                }
                ho_Image.Dispose();
                return;
            }
            catch (HalconException HDevExpDefaultException)
            {
                ho_Image.Dispose();
            }

        }

        public HalconWindowProcess()
        {

            hv_TrackballSize = 0.8;

            hv_MouseMapping = new HTuple();
            hv_MouseMapping[0] = 17;
            hv_MouseMapping[1] = 1;
            hv_MouseMapping[2] = 2;
            hv_MouseMapping[3] = 5;
            hv_MouseMapping[4] = 9;
            hv_MouseMapping[5] = 4;
            hv_MouseMapping[6] = 49;

            ExpTmpLocalVar_gInfoDecor = new HTuple();
            ExpTmpLocalVar_gInfoDecor[0] = "white";
            ExpTmpLocalVar_gInfoDecor[1] = "false";
            ExpSetGlobalVar_gInfoDecor(ExpTmpLocalVar_gInfoDecor);
            ExpTmpLocalVar_gLabelsDecor = new HTuple();
            ExpTmpLocalVar_gLabelsDecor[0] = "white";
            ExpTmpLocalVar_gLabelsDecor[1] = "false";
            ExpSetGlobalVar_gLabelsDecor(ExpTmpLocalVar_gLabelsDecor);
            ExpTmpLocalVar_gTitleDecor = new HTuple();
            ExpTmpLocalVar_gTitleDecor[0] = "black";
            ExpTmpLocalVar_gTitleDecor[1] = "true";
            ExpSetGlobalVar_gTitleDecor(ExpTmpLocalVar_gTitleDecor);

            ExpTmpLocalVar_gDispObjOffset = new HTuple();
            ExpTmpLocalVar_gDispObjOffset[0] = -30;
            ExpTmpLocalVar_gDispObjOffset[1] = 0;
            ExpSetGlobalVar_gDispObjOffset(ExpTmpLocalVar_gDispObjOffset);
            //
            // 自定义不同文本元素的装饰
            //颜色，盒子

            //
            // 自定义某些文本元素的位置
            //gfopops有一个值
            //{ 'UpPurLead’，'LeLeLeLe''，'Uptrue' }
            ExpTmpLocalVar_gInfoPos = "LowerLeft";
            ExpSetGlobalVar_gInfoPos(ExpTmpLocalVar_gInfoPos);
            //  gTitlePos has one of the values
            //  {'UpperLeft', 'UpperCenter', 'UpperRight'}
            ExpTmpLocalVar_gTitlePos = "UpperLeft";
            ExpSetGlobalVar_gTitlePos(ExpTmpLocalVar_gTitlePos);
            // 用于可视化的α值（＝1透明度）
            //未被选择的对象
            ExpTmpLocalVar_gAlphaDeselected = 0.3;
            ExpSetGlobalVar_gAlphaDeselected(ExpTmpLocalVar_gAlphaDeselected);
            //自定义“继续”按钮的标签
            ExpTmpLocalVar_gTerminationButtonLabel = " Continue ";
            ExpSetGlobalVar_gTerminationButtonLabel(ExpTmpLocalVar_gTerminationButtonLabel);
            hv_WaitForButtonRelease = "false";
            hv_MaxNumModels = 1000;
            hv_WindowCenteredRotation = 2;
        }

        HTuple hv_MaxNumModels = null;
        HTuple ExpTmpLocalVar_gDispObjOffset = null;
        HTuple hv_WindowCenteredRotation = null;
        HTuple ExpTmpLocalVar_gInfoPos = null, ExpTmpLocalVar_gTitlePos = null;
        HTuple ExpTmpLocalVar_gTerminationButtonLabel = null;
        HTuple ExpTmpLocalVar_gAlphaDeselected = null;
        HTuple hv_MouseMapping = null;
        HTuple hv_TrackballSize = null;
        HTuple ExpTmpLocalVar_gLabelsDecor = null, ExpTmpLocalVar_gInfoDecor = null, ExpTmpLocalVar_gTitleDecor = null;
        HTuple hv_WaitForButtonRelease = null;

        public void get_trackball_center_fixed(HTuple hv_SelectedObject, HTuple hv_TrackballCenterRow,
            HTuple hv_TrackballCenterCol, HTuple hv_TrackballRadiusPixel, HTuple hv_Scene3D,
            HTuple hv_ObjectModel3DID, HTuple hv_Poses, HTuple hv_WindowHandleBuffer, HTuple hv_CamParam,
            HTuple hv_GenParamName, HTuple hv_GenParamValue, out HTuple hv_TBCenter, out HTuple hv_TBSize)
        {



            // Local iconic variables 

            HObject ho_RegionCenter, ho_DistanceImage;
            HObject ho_Domain;

            // Local control variables 

            HTuple hv_NumModels = null, hv_Width = null;
            HTuple hv_Height = null, hv_SelectPose = null, hv_Index1 = null;
            HTuple hv_Rows = null, hv_Columns = null, hv_Grayval = null;
            HTuple hv_IndicesG = null, hv_Value = null, hv_Pos = null;
            // Initialize local and output iconic variables 
            HOperatorSet.GenEmptyObj(out ho_RegionCenter);
            HOperatorSet.GenEmptyObj(out ho_DistanceImage);
            HOperatorSet.GenEmptyObj(out ho_Domain);
            hv_TBCenter = new HTuple();
            hv_TBSize = new HTuple();
            try
            {
                //Determine the trackball center for the fixed trackball
                hv_NumModels = new HTuple(hv_ObjectModel3DID.TupleLength());
                get_cam_par_data(hv_CamParam, "image_width", out hv_Width);
                get_cam_par_data(hv_CamParam, "image_height", out hv_Height);
                //
                //Project the selected objects
                hv_SelectPose = new HTuple();
                for (hv_Index1 = 0; (int)hv_Index1 <= (int)((new HTuple(hv_SelectedObject.TupleLength()
                    )) - 1); hv_Index1 = (int)hv_Index1 + 1)
                {
                    hv_SelectPose = hv_SelectPose.TupleConcat(HTuple.TupleGenConst(7, hv_SelectedObject.TupleSelect(
                        hv_Index1)));
                    if ((int)(new HTuple(((hv_SelectedObject.TupleSelect(hv_Index1))).TupleEqual(
                        0))) != 0)
                    {
                        HOperatorSet.SetScene3dInstanceParam(hv_Scene3D, hv_Index1, "visible",
                            "false");
                    }
                }
                HOperatorSet.SetScene3dParam(hv_Scene3D, "depth_persistence", "true");
                HOperatorSet.DisplayScene3d(hv_ExpDefaultWinHandle, hv_Scene3D, 0);
                HOperatorSet.SetScene3dParam(hv_Scene3D, "visible", "true");
                //
                //determine the depth of the object point that appears closest to the trackball
                //center
                ho_RegionCenter.Dispose();
                HOperatorSet.GenRegionPoints(out ho_RegionCenter, hv_TrackballCenterRow, hv_TrackballCenterCol);
                ho_DistanceImage.Dispose();
                HOperatorSet.DistanceTransform(ho_RegionCenter, out ho_DistanceImage, "chamfer-3-4-unnormalized",
                    "false", hv_Width, hv_Height);
                ho_Domain.Dispose();
                HOperatorSet.GetDomain(ho_DistanceImage, out ho_Domain);
                HOperatorSet.GetRegionPoints(ho_Domain, out hv_Rows, out hv_Columns);
                HOperatorSet.GetGrayval(ho_DistanceImage, hv_Rows, hv_Columns, out hv_Grayval);
                HOperatorSet.TupleSortIndex(hv_Grayval, out hv_IndicesG);
                HOperatorSet.GetDisplayScene3dInfo(hv_ExpDefaultWinHandle, hv_Scene3D, hv_Rows.TupleSelect(
                    hv_IndicesG), hv_Columns.TupleSelect(hv_IndicesG), "depth", out hv_Value);
                HOperatorSet.TupleFind(hv_Value.TupleSgn(), 1, out hv_Pos);
                //
                HOperatorSet.SetScene3dParam(hv_Scene3D, "depth_persistence", "false");
                //
                //
                //set TBCenter
                if ((int)(new HTuple(hv_Pos.TupleNotEqual(-1))) != 0)
                {
                    //if the object is visible in the image
                    hv_TBCenter = new HTuple();
                    hv_TBCenter[0] = 0;
                    hv_TBCenter[1] = 0;
                    hv_TBCenter = hv_TBCenter.TupleConcat(hv_Value.TupleSelect(
                        hv_Pos.TupleSelect(0)));
                }
                else
                {
                    //if the object is not visible in the image, set the z coordinate to -1
                    //to indicate, the the previous z value should be used instead
                    hv_TBCenter = new HTuple();
                    hv_TBCenter[0] = 0;
                    hv_TBCenter[1] = 0;
                    hv_TBCenter[2] = -1;
                }
                //
                if ((int)(new HTuple(((hv_SelectedObject.TupleMax())).TupleNotEqual(0))) != 0)
                {
                    hv_TBSize = (0.5 + ((0.5 * (hv_SelectedObject.TupleSum())) / hv_NumModels)) * hv_TrackballRadiusPixel;
                }
                else
                {
                    hv_TBCenter = new HTuple();
                    hv_TBSize = 0;
                }
                ho_RegionCenter.Dispose();
                ho_DistanceImage.Dispose();
                ho_Domain.Dispose();

                return;
            }
            catch (HalconException HDevExpDefaultException)
            {
                ho_RegionCenter.Dispose();
                ho_DistanceImage.Dispose();
                ho_Domain.Dispose();

                throw HDevExpDefaultException;
            }
        }

        // 计算3d模型中心 
        public void get_object_models_center(HTuple hv_ObjectModel3DID, out HTuple hv_Center)
        {



            // Local iconic variables 

            // Local control variables 

            HTuple hv_Diameter = new HTuple(), hv_MD = new HTuple();
            HTuple hv_Weight = new HTuple(), hv_SumW = new HTuple();
            HTuple hv_Index = new HTuple(), hv_ObjectModel3DIDSelected = new HTuple();
            HTuple hv_C = new HTuple(), hv_InvSum = new HTuple();
            // Initialize local and output iconic variables 
            hv_Center = new HTuple();
            //模型数量大于零
            if ((int)hv_ObjectModel3DID.TupleLength()>0)
            {
                HOperatorSet.GetObjectModel3dParams(hv_ObjectModel3DID, "diameter_axis_aligned_bounding_box",
                    out hv_Diameter);
                //Normalize Diameter to use it as weights for a weighted mean of the individual centers
                hv_MD = hv_Diameter.TupleMean();
                if ((int)(new HTuple(hv_MD.TupleGreater(1e-10))) != 0)
                {
                    hv_Weight = hv_Diameter / hv_MD;
                }
                else
                {
                    hv_Weight = hv_Diameter.Clone();
                }
                hv_SumW = hv_Weight.TupleSum();
                if ((int)(new HTuple(hv_SumW.TupleLess(1e-10))) != 0)
                {
                    hv_Weight = HTuple.TupleGenConst(new HTuple(hv_Weight.TupleLength()), 1.0);
                    hv_SumW = hv_Weight.TupleSum();
                }
                hv_Center = new HTuple();
                hv_Center[0] = 0;
                hv_Center[1] = 0;
                hv_Center[2] = 0;
                for (hv_Index = 0; (int)hv_Index <= (int)((new HTuple(hv_ObjectModel3DID.TupleLength()
                    )) - 1); hv_Index = (int)hv_Index + 1)
                {
                    hv_ObjectModel3DIDSelected = hv_ObjectModel3DID.TupleSelect(hv_Index);
                    HOperatorSet.GetObjectModel3dParams(hv_ObjectModel3DIDSelected, "center",
                        out hv_C);
                    if (hv_Center == null)
                        hv_Center = new HTuple();
                    hv_Center[0] = (hv_Center.TupleSelect(0)) + ((hv_C.TupleSelect(0)) * (hv_Weight.TupleSelect(
                        hv_Index)));
                    if (hv_Center == null)
                        hv_Center = new HTuple();
                    hv_Center[1] = (hv_Center.TupleSelect(1)) + ((hv_C.TupleSelect(1)) * (hv_Weight.TupleSelect(
                        hv_Index)));
                    if (hv_Center == null)
                        hv_Center = new HTuple();
                    hv_Center[2] = (hv_Center.TupleSelect(2)) + ((hv_C.TupleSelect(2)) * (hv_Weight.TupleSelect(
                        hv_Index)));
                }
                hv_InvSum = 1.0 / hv_SumW;
                if (hv_Center == null)
                    hv_Center = new HTuple();
                hv_Center[0] = (hv_Center.TupleSelect(0)) * hv_InvSum;
                if (hv_Center == null)
                    hv_Center = new HTuple();
                hv_Center[1] = (hv_Center.TupleSelect(1)) * hv_InvSum;
                if (hv_Center == null)
                    hv_Center = new HTuple();
                hv_Center[2] = (hv_Center.TupleSelect(2)) * hv_InvSum;
            }
            else
            {
                hv_Center = new HTuple();
            }

            return;
        }

        
        //简短描述：在缓冲区窗口中渲染3D对象模型。
        public void dump_image_output(HObject ho_BackgroundImage, HTuple hv_WindowHandleBuffer,
            HTuple hv_Scene3D, HTuple hv_AlphaOrig, HTuple hv_ObjectModel3DID, HTuple hv_GenParamName,
            HTuple hv_GenParamValue, HTuple hv_CamParam, HTuple hv_Poses,
            HTuple hv_SelectedObject)
        {
            // Local iconic variables 
            HObject ho_ModelContours = null;

            // Local control variables 
            HTuple hv_Exception = new HTuple(), hv_Index = new HTuple();
            HTuple hv_Exception1 = new HTuple(), hv_DeselectedIdx = new HTuple();
            HTuple hv_DeselectedName = new HTuple(), hv_DeselectedValue = new HTuple();

            // Initialize local and output iconic variables 
            HOperatorSet.GenEmptyObj(out ho_ModelContours);
            try
            {
                HSystem.SetSystem("flush_graphic", "false");//关闭窗口刷新
                HOperatorSet.ClearWindow(hv_ExpDefaultWinHandle);


                HOperatorSet.DispImage(ho_BackgroundImage, hv_ExpDefaultWinHandle);

                //
                //Display objects
                if (hv_SelectedObject.TupleSum() == hv_SelectedObject.TupleLength())
                {
                    if (gUsesOpenGL == "true")
                    {
                        try
                        {
                            HOperatorSet.DisplayScene3d(hv_ExpDefaultWinHandle, hv_Scene3D, 0);
                        }
                        // catch (Exception) 
                        catch (HalconException HDevExpDefaultException1)
                        {
                            HDevExpDefaultException1.ToHTuple(out hv_Exception);
                            if ((hv_Exception.TupleSelect(0) == 5185) | (hv_Exception.TupleSelect(0) == 5188) | (hv_Exception.TupleSelect(0) == 5187))
                            {
                                gUsesOpenGL = "false";
                            }
                            else
                            {
                                throw new HalconException(hv_Exception);
                            }
                        }
                    }
                    if (gUsesOpenGL == "false")
                    {
                        //* NO OpenGL, use fallback
                        ho_ModelContours.Dispose();
                        disp_object_model_no_opengl(out ho_ModelContours, hv_ObjectModel3DID, hv_GenParamName,
                            hv_GenParamValue, hv_ExpDefaultWinHandle, hv_CamParam, hv_Poses);
                    }
                }
                else
                {
                    for (hv_Index = 0; hv_Index < hv_AlphaOrig.TupleLength(); hv_Index++)
                    {
                        if (hv_SelectedObject.TupleSelect(hv_Index) == 1)
                        {
                            HOperatorSet.SetScene3dInstanceParam(hv_Scene3D, hv_Index, "alpha", hv_AlphaOrig.TupleSelect(
                                hv_Index));
                        }
                        else
                        {
                            HOperatorSet.SetScene3dInstanceParam(hv_Scene3D, hv_Index, "alpha", ExpGetGlobalVar_gAlphaDeselected());
                        }
                    }
                    try
                    {
                        if (ExpGetGlobalVar_gUsesOpenGL() == "false")
                        {
                            throw new HalconException(new HTuple());
                        }
                        HOperatorSet.DisplayScene3d(hv_ExpDefaultWinHandle, hv_Scene3D, 0);
                    }
                    // catch (Exception1) 
                    catch (HalconException HDevExpDefaultException1)
                    {
                        HDevExpDefaultException1.ToHTuple(out hv_Exception1);
                        //* NO OpenGL, use fallback
                        hv_DeselectedIdx = hv_SelectedObject.TupleFind(0);
                        if ((int)(new HTuple(hv_DeselectedIdx.TupleNotEqual(-1))) != 0)
                        {
                            hv_DeselectedName = "color_" + hv_DeselectedIdx;
                            hv_DeselectedValue = HTuple.TupleGenConst(new HTuple(hv_DeselectedName.TupleLength()
                                ), "gray");
                        }
                        ho_ModelContours.Dispose();
                        disp_object_model_no_opengl(out ho_ModelContours, hv_ObjectModel3DID, hv_GenParamName.TupleConcat(
                            hv_DeselectedName), hv_GenParamValue.TupleConcat(hv_DeselectedValue),
                            hv_ExpDefaultWinHandle, hv_CamParam, hv_Poses);
                    }
                    for (hv_Index = 0; (int)hv_Index <= (int)((new HTuple(hv_AlphaOrig.TupleLength()
                        )) - 1); hv_Index = (int)hv_Index + 1)
                    {
                        HOperatorSet.SetScene3dInstanceParam(hv_Scene3D, hv_Index, "alpha", hv_AlphaOrig.TupleSelect(
                            hv_Index));
                    }
                }
                HSystem.SetSystem("flush_graphic", "true");  //打开窗口刷新
                HOperatorSet.DispLine(hv_ExpDefaultWinHandle, -100.0, -100.0, -101.0, -101.0);
                ho_ModelContours.Dispose();

                return;
            }
            catch (HalconException HDevExpDefaultException)
            {
                ho_ModelContours.Dispose();

                throw HDevExpDefaultException;
            }
        }

        // Chapter: Graphics / Output
        // Short Description: Get the center of the virtual trackback that is used to move the camera. 
        public void get_trackball_center(HTuple hv_SelectedObject, HTuple hv_TrackballRadiusPixel,
            HTuple hv_ObjectModel3D, HTuple hv_Poses, out HTuple hv_TBCenter, out HTuple hv_TBSize)
        {



            // Local iconic variables 

            // Local control variables 

            HTuple hv_NumModels = null, hv_Centers = null;
            HTuple hv_Diameter = null, hv_MD = null, hv_Weight = new HTuple();
            HTuple hv_SumW = null, hv_Index = null, hv_ObjectModel3DIDSelected = new HTuple();
            HTuple hv_PoseSelected = new HTuple(), hv_HomMat3D = new HTuple();
            HTuple hv_TBCenterCamX = new HTuple(), hv_TBCenterCamY = new HTuple();
            HTuple hv_TBCenterCamZ = new HTuple(), hv_InvSum = new HTuple();
            // Initialize local and output iconic variables 
            hv_TBCenter = new HTuple();
            hv_TBSize = new HTuple();
            hv_NumModels = new HTuple(hv_ObjectModel3D.TupleLength());
            if (hv_TBCenter == null)
                hv_TBCenter = new HTuple();
            hv_TBCenter[0] = 0;
            if (hv_TBCenter == null)
                hv_TBCenter = new HTuple();
            hv_TBCenter[1] = 0;
            if (hv_TBCenter == null)
                hv_TBCenter = new HTuple();
            hv_TBCenter[2] = 0;
            HOperatorSet.GetObjectModel3dParams(hv_ObjectModel3D, "center", out hv_Centers);
            HOperatorSet.GetObjectModel3dParams(hv_ObjectModel3D, "diameter_axis_aligned_bounding_box",
                out hv_Diameter);
            //Normalize Diameter to use it as weights for a weighted mean of the individual centers
            hv_MD = hv_Diameter.TupleMean();
            if ((int)(new HTuple(hv_MD.TupleGreater(1e-10))) != 0)
            {
                hv_Weight = hv_Diameter / hv_MD;
            }
            else
            {
                hv_Weight = hv_Diameter.Clone();
            }
            hv_SumW = ((hv_Weight.TupleSelectMask(((hv_SelectedObject.TupleSgn())).TupleAbs()
                ))).TupleSum();
            if ((int)(new HTuple(hv_SumW.TupleLess(1e-10))) != 0)
            {
                hv_Weight = HTuple.TupleGenConst(new HTuple(hv_Weight.TupleLength()), 1.0);
                hv_SumW = ((hv_Weight.TupleSelectMask(((hv_SelectedObject.TupleSgn())).TupleAbs()
                    ))).TupleSum();
            }
            HTuple end_val18 = hv_NumModels - 1;
            HTuple step_val18 = 1;
            for (hv_Index = 0; hv_Index.Continue(end_val18, step_val18); hv_Index = hv_Index.TupleAdd(step_val18))
            {
                if ((int)(hv_SelectedObject.TupleSelect(hv_Index)) != 0)
                {
                    hv_ObjectModel3DIDSelected = hv_ObjectModel3D.TupleSelect(hv_Index);
                    hv_PoseSelected = hv_Poses.TupleSelectRange(hv_Index * 7, (hv_Index * 7) + 6);
                    HOperatorSet.PoseToHomMat3d(hv_PoseSelected, out hv_HomMat3D);
                    HOperatorSet.AffineTransPoint3d(hv_HomMat3D, hv_Centers.TupleSelect((hv_Index * 3) + 0),
                        hv_Centers.TupleSelect((hv_Index * 3) + 1), hv_Centers.TupleSelect((hv_Index * 3) + 2),
                        out hv_TBCenterCamX, out hv_TBCenterCamY, out hv_TBCenterCamZ);
                    if (hv_TBCenter == null)
                        hv_TBCenter = new HTuple();
                    hv_TBCenter[0] = (hv_TBCenter.TupleSelect(0)) + (hv_TBCenterCamX * (hv_Weight.TupleSelect(
                        hv_Index)));
                    if (hv_TBCenter == null)
                        hv_TBCenter = new HTuple();
                    hv_TBCenter[1] = (hv_TBCenter.TupleSelect(1)) + (hv_TBCenterCamY * (hv_Weight.TupleSelect(
                        hv_Index)));
                    if (hv_TBCenter == null)
                        hv_TBCenter = new HTuple();
                    hv_TBCenter[2] = (hv_TBCenter.TupleSelect(2)) + (hv_TBCenterCamZ * (hv_Weight.TupleSelect(
                        hv_Index)));
                }
            }
            if ((int)(new HTuple(((hv_SelectedObject.TupleMax())).TupleNotEqual(0))) != 0)
            {
                hv_InvSum = 1.0 / hv_SumW;
                if (hv_TBCenter == null)
                    hv_TBCenter = new HTuple();
                hv_TBCenter[0] = (hv_TBCenter.TupleSelect(0)) * hv_InvSum;
                if (hv_TBCenter == null)
                    hv_TBCenter = new HTuple();
                hv_TBCenter[1] = (hv_TBCenter.TupleSelect(1)) * hv_InvSum;
                if (hv_TBCenter == null)
                    hv_TBCenter = new HTuple();
                hv_TBCenter[2] = (hv_TBCenter.TupleSelect(2)) * hv_InvSum;
                hv_TBSize = (0.5 + ((0.5 * (hv_SelectedObject.TupleSum())) / hv_NumModels)) * hv_TrackballRadiusPixel;
            }
            else
            {
                hv_TBCenter = new HTuple();
                hv_TBSize = 0;
            }

            return;
        }


    }
}
